为啥滚动 UITableView 比滚动 UIScrollView 响应更快?

Posted

技术标签:

【中文标题】为啥滚动 UITableView 比滚动 UIScrollView 响应更快?【英文标题】:Why is scrolling a UITableView much more responsive than scrolling a UIScrollView?为什么滚动 UITableView 比滚动 UIScrollView 响应更快? 【发布时间】:2012-05-11 10:23:13 【问题描述】:

注意:这不是性能问题!我知道 UITableView 中单元格出列的好处。

为了测试,我创建了一个 UIScrollView,其中包含一些简单的不透明 UIView 子视图,这些子视图在白色滚动视图上具有黑色背景色,它们之间的间距为 100 点,因此可以滚动。重量很轻。没有其他的。真的相信我,它并不重。

我注意到开始滚动滚动视图和开始滚动表格视图之间存在巨大差异。

当我触摸滚动视图并立即开始拖动时,它滞后了大约 0.25 秒,然后突然赶上了。从那里开始它是流畅的,在我再次触地之前不再滞后。

在更大、更复杂的 UITableView 上,当我做同样的事情时,在它开始滚动之前没有 0.25 秒的初始延迟。

我尝试更改所有可能的属性,但无法消除这种愚蠢的延迟。我相信它与滚动视图有关,想要确定触摸是否打算在子视图上发生,然后查看用户是否移动它的手指太多。然后它开始滚动。

现在疯狂的是 UITableView 本身就是一个 UIScrollView,我想让我的 UIScrollView 开始像 UITableView 一样快地滚动。怎么样?

编辑:嘘..我发现了一些疯狂的东西!

NSLog(@"GR = %@", self.gestureRecognizers);


GR = (

"<UIScrollViewDelayedTouchesBeganGestureRecognizer: 0x13e930; 
state = Possible; 
delaysTouchesBegan = YES; 
view = <TestScrollView 0x13e380>; 
target= <(action=delayed:, target=<TestScrollView 0x13e380>)>>",

"<UIScrollViewPanGestureRecognizer: 0x13ee00; 
state = Possible; 
delaysTouchesEnded = NO; 
view = <TestScrollView 0x13e380>; 
target= <(action=handlePan:, target=<TestScrollView 0x13e380>)>>"

)

这是 ios 4,iOS4 中没有 panGestureRecognizer 属性。最可疑的是 UIScrollViewDelayedTouchesBeganGestureRecognizer 和 delaysTouchesBegan。该死! 如何在 iOS4 中将其设置为 NO

【问题讨论】:

【参考方案1】:

编辑:

我找到了this answer in S.O。

基本上,您可以尝试继承 UIScrollView 并覆盖 touchesShouldCancelInContentView 以便它始终返回 NO:

- (BOOL)touchesShouldCancelInContentView:(UIView *)view

      return NO;

上一个答案:

我尝试更改所有可能的属性,但无法消除这种愚蠢的延迟。我相信它与滚动视图有关,想要确定触摸是否打算在子视图上发生,然后查看用户是否移动它的手指太多。然后它开始滚动。

我认为这是正确的假设。事实上,响应者链和事件管理的设计方式是,最具体的视图是接收事件通知的视图;在此过程中,会询问响应者链中的每个视图,直到找到最深的视图。

触摸事件。窗口对象使用命中测试和响应者链来找到接收触摸事件的视图。在命中测试中,窗口在视图层次结构的最顶层视图上调用 hitTest:withEvent:;此方法通过在视图层次结构中返回 YES 的每个视图上递归调用 pointInside:withEvent: 来继续,沿着层次结构向下进行,直到找到发生触摸的子视图。该视图成为命中测试视图。

(source)

可能UITableView 做了一些改变这种行为的事情。

让您的滚动视图成为第一响应者:

 [scrollView becomeFirstResponder]

不会起作用,因为这只会影响非触摸事件的分派。

您可以尝试让内部视图不启用触摸功能,看看是否会有所不同。

【讨论】:

猜得好。我尝试禁用内部视图的用户交互,但没有效果。 -touchesShouldCancelInContentView: 完全没有效果。【参考方案2】:

你试过subViews.userInteractionEnabled = NO;吗?这将帮助您消除触摸假设。

【讨论】:

是的,这不是根本原因。

以上是关于为啥滚动 UITableView 比滚动 UIScrollView 响应更快?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 UITableView 只在输入第一个字符时自动滚动?

为啥 UITableView 滚动时会更新约束?

如何在 UIViewController 的 tableView 顶部添加自定义视图并能够一起滚动

为啥我的 UITableView 单元格在滚动时重叠?

为啥第一次滚动到另一个 UITableView 中的 UICollectionView 中的 UITableView 不加载数据?

为啥我的子类 UItableView 不滚动?