3

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

目前,PlaceDetailsViewController.view作为UIScrollView一个容器,我正在添加DiscountListTableViewController.tableView到这个UIScrollView.content容器中viewDidLoadPlaceDetailsViewController. 这有效并且表格视图正确显示,但无法接收单元格点击。

我知道UITableView继承自UIScrollView并且不知何故不建议(但不受限制)。但是,从松耦合的角度来看,每个组件都应该以可以在其他地方独立使用的方式设计,就DiscountListTableViewController我而言。

PlaceDetailsViewController组件只需要DiscountListTableViewController原样,因此没有逻辑理由不能直接使用它。有什么建议么?

4

6 回答 6

28

答:不要这样做。

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

苹果 说:

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

于 2013-06-15T08:18:32.980 回答
7

不建议?读完后有种“不要做”的感觉。不可预测性对应用程序来说从来都不是一个好的行为

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

于 2013-06-15T08:15:34.550 回答
4

2020 年更新,Swift 5.X 让您tableviewscrollview!

  1. 创建 UITableView 的子类:

     import UIKit
    
     final class ContentSizedTableView: UITableView {
         override var contentSize:CGSize {
             didSet {
                 invalidateIntrinsicContentSize()
             }
         }
    
         override var intrinsicContentSize:CGSize {
             layoutIfNeeded()
             return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
         }
     }
    
  2. 将 UITableView 添加到您的布局并在所有方面设置约束。将它的类设置为 ContentSizedTableView。

  3. 您应该会看到一些错误,因为 Storyboard 没有考虑到我们的子类intrinsicContentSize。在运行时,它将使用 ContentSizedTableView 类中的覆盖

于 2020-04-15T09:02:26.347 回答
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];
}
于 2013-06-15T09:14:45.240 回答
0

不应该这样做,因为 UITableView 是 UIScrollView 的子类并且根据苹果文档。只需使用自动布局比计算每个项目大小和停止表滚动更容易。

苹果文档

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

于 2019-01-25T11:50:37.707 回答
0

也许这已经晚了,但我设法做到了:

  • 在 UITableView 上禁用滚动
  • 计算出我需要的高度后,以编程方式设置 UIScrollView 的内容大小
于 2018-10-29T13:33:29.870 回答