如何在UIScrollView中使用UITableView并接收单元格?

时间:2013-06-15 08:04:43

标签: iphone ios objective-c uitableview uiscrollview

我的DiscountListTableViewController在我的应用中显示为单独的屏幕。但是还有另一个屏幕(PlaceDetailsViewController),我需要在底部显示相关的折扣。

目前,PlaceDetailsViewController.view已将UIScrollView作为容器,我将DiscountListTableViewController.tableView添加到UIScrollView.content viewDidLoad PlaceDetailsViewControllerUITableView容器中。这样可以正常显示表格视图,但无法接收单元格点击。

我知道UIScrollView继承自DiscountListTableViewController并且不知何为(但不限制)。但是,从松散耦合的角度来看,每个组件的设计应该可以在其他地方独立使用,在我的情况下它是PlaceDetailsViewController

DiscountListTableViewController组件只需要{{1}},因此无法直接使用它的逻辑原因。有什么建议?

6 个答案:

答案 0 :(得分:24)

答案:不要这样做。

UITableview继承自----> UIScrollView : UIView : UIResponder : NSObject

Apple说:

  

重要提示:您不应该嵌入UIWebView或UITableView对象   UIScrollView对象。如果这样做,可能会导致意外行为   因为两个对象的触摸事件可能混淆错误   处理。

答案 1 :(得分:6)

不建议?它有点像"不做"阅读之后。不可预测性从来都不是应用程序的好行为

  

重要提示:您不应该嵌入UIWebView或UITableView对象   UIScrollView对象。如果这样做,可能会导致意外行为   因为两个对象的触摸事件可能混淆错误   处理。

答案 2 :(得分:2)

将分享如何解决这个问题。子类化了UIScrollView并在PlaceDetailsViewController中用作容器视图:

@interface PlaceDetailsContainerUIScrollView : UIScrollView

@end

@implementation PlaceDetailsContainerUIScrollView

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
  UIView *result = [super hitTest:point withEvent:event];

  if ([result isKindOfClass:[UIView class]] && (result.tag == kDiscountListTableViewCellTag)
  {
    UITableView *tableView = (UITableView *) [[result.superview superview] superview];

    return tableView;

  }

  return result;
}
@end

另外,不要忘记设置PlaceDetailsContainerUIScrollView.delaysContentTouches = YES和PlaceDetailsContainerUIScrollView.canCancelContentTouches = NO。

此外,在DiscountListTableViewController方法中需要小修复:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  DiscountDetailsViewController *discountDetailsVC = [[DiscountDetailsViewController alloc] init];

  //[self.navigationController pushViewController:discountDetailsVC animated:YES];   
  // self.navigationController is nill because it's not pushed on nav stack, so will grab the current one:
  AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

  [appDelegate.navigationController pushViewController:discountDetailsVC animated:YES];
}

答案 3 :(得分:1)

为2020年更新,迅速的5.X允许您的class MoviePagerAdapter extends FragmentStatePagerAdapter { public ArrayList<Fragment> items = new ArrayList<Fragment>(); @Override public Fragment getItem(int position) { return items.get(position); } public MoviePagerAdapter(@NonNull FragmentManager fm) { super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); } public void addItem(Fragment item) { items.add(item); } @Override public int getCount() { return items.size(); } } 放在public class MainFragment extends androidx.fragment.app.Fragment { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.main_frargment, container, false); //... 'i want to make 6fragments with datas below ' movieData = new MovieData("title1", "rate1", "grade1"); addData(movieData); movieData = new MovieData("title2", "rate2", "grade2"); addData(movieData); movieData = new MovieData("title3", "rate3", "grade3"); addData(movieData); movieData = new MovieData("title4", "rate4", "grade4"); addData(movieData); movieData = new MovieData("title5", "rate5", "grade5"); addData(movieData); movieData = new MovieData("title6", "rate6", "grade6"); addData(movieData); return rootView; } public void addData(MovieData movieData){ Bundle bundle = new Bundle(); bundle.putParcelable("data", movieData); MainFragment mainFragment = new MainFragment(); mainFragment.setArguments(bundle); title.setText(movieData.title); reservation_rate.setText(movieData.getReservation_rate()); grade.setText(movieData.getGrade()); image.setImageResource(R.drawable.image6); } 中!

  1. 创建UITableView的子类:

    tableview
  2. 向您的布局添加一个UITableView并在所有方面设置约束。将其类设置为ContentSizedTableView。

  3. 您应该看到一些错误,因为Storyboard并未考虑我们的子类'scrollview。在运行时,它将使用我们的ContentSizedTableView类中的替代

答案 4 :(得分:0)

也许这很晚了,但是我设法做到了:

  • 在UITableView上禁用滚动
  • 在计算所需高度后,以编程方式设置UIScrollView的内容大小

答案 5 :(得分:0)

不应这样做,因为根据Apple docs,UITableView是UIScrollView的子类。 只需使用auto layout比计算每个项目大小和停止表格滚动更容易。

苹果Docs

您不应在UIScrollView对象中嵌入UIWebView或UITableView对象。如果这样做,可能会导致意外行为,因为两个对象的触摸事件可能会混合在一起并且处理不当。