具有水平滚动的嵌套 UIScrollViews

Posted

技术标签:

【中文标题】具有水平滚动的嵌套 UIScrollViews【英文标题】:Nested UIScrollViews with horizontal scrolling for both 【发布时间】:2013-07-08 11:58:14 【问题描述】:

我在另一个里面有一个嵌套的UIScrollView,两者都是水平的。

外层包含多个UIScrollViews,假设每页一个(多页的文档)。 内部的可以只包含一个适合屏幕的UIView,或者可能包含一些更大的UIView,也应该滚动(通常是水平的,但如果用户捏住屏幕,那么他可以双向滚动)。

当我快速滚动文档并且外部滚动视图只是决定滚动其子视图,而不让内部滚动视图(那些 contentSize 大于屏幕大小的)滚动时,就会出现问题。 如果我轻轻滚动外部滚动视图,它也会让内部滚动视图也滚动。

期望的行为是,即使我快速滚动外部滚动视图,它也应该滚动内部滚动视图,直到其内容完全显示,然后才让外部滚动视图滚动。

我尝试覆盖hitTest:withEvent:,以便外部滚动视图应该询问其当前可见的UIScrollView 子视图是否应该滚动,但这目前仅在向前滚动时有效。问题是我无法在hitTest:withEvent: 中检测到滚动方向,所以我也在考虑将这段代码移到其他地方,但我不知道这是否是正确的方法。

我很抱歉句子中的所有“滚动”词,但我不知道如何更好地解释这一点

【问题讨论】:

scrollview inside scrollview 不是苹果推荐的模式。它会带来不可预知的结果 这里developer.apple.com/library/ios/#documentation/WindowsViews/… 他们说它受支持。不幸的是,我看不到任何其他方式来实现这一点。此外,我正在开发一个大型代码库,除非这是唯一的选择,否则我们不太可能重构它 它还说 注意:支持这种同向滚动,并且为该功能定义了不同的行为,但是该行为可能会在未来的 iOS 版本中发生变化. 【参考方案1】:

如果外部 scrollView 仍然动画移动,它将获取所有手势,而不是让内部处理它们。

您可以尝试使用gestureRecognizer 的requireGestureRecognizerToFail: 方法,这样外部滚动视图的panGestureRecognizer 需要外部滚动视图的panGestureRecognizers 才能失败。它可能会使滚动感觉有点迟钝,我不确定这是否能解决您的问题,但是嘿,尝试一下也无妨。

【讨论】:

我实施了您建议的解决方案。一切都按预期工作,但现在滚动当然只有在我抬起手指时才会发生。这是违反直觉的,但我认为如果以这种方式实施,则无法解决。 我在我的一个应用程序中遇到了类似的问题,但我应该让外部滚动视图只对两指滚动作出反应。所以我只是在内部滚动视图中禁用 panGestureRecognizer 并添加 UISwipeGestureRecognizers 来左右移动,现在运行流畅。如果在您的应用中将外部滚动限制为 2 指手势和内部视图中的某种分页是可以接受的,您可以尝试这样做。 很遗憾,我不能引入两指手势,因为用户交互必须相同。我将尝试重构外部滚动视图类,通过增加特定页面的框架大小来增加将双页管理为单页的可能性,这样我实际上就不需要滚动内部滚动视图。

以上是关于具有水平滚动的嵌套 UIScrollViews的主要内容,如果未能解决你的问题,请参考以下文章

QML中具有嵌套滚动区域的二维表

具有共享滚动手势的嵌套 UITableView

使用嵌套适配器垂直滚动时出现滞后问题 | IGListKit

嵌套在 BottomSheet 中的 RecyclerView(水平)防止垂直滚动

ExtJS 6.0.2 使用 hbox 布局创建具有两个嵌套面板的面板

SwiftUI Drag 事件如何限制仅检测水平/垂直滚动