我的视图层次结构如下。
ParentContainerVC
..UINavigationViewController (child of ParentContainerVC)
....UITableViewController (child of navigation view controller)
..UICollectionViewController (child of ParentContainerVC)
滚动事件已由托管UICollectionView的VC正确拦截,但是下面的UITableView仍然冻结。两者的大小都可以占据屏幕的整个宽度/高度,但是应该允许它们独立滚动(UICollectionView不会掩盖下面的UITableView,以防您想知道-但是用户需要能够在同时)。
在托管集合视图的VC中,我已实现:
extension UICollectionViewController: UIGestureRecognizerDelegate {
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
但是这没有帮助。我认为这是因为视图控制器已被添加为子控制器,并且无法在同级视图控制器中使用。
ParentContainerVC
只是具有两个子代的容器视图控制器。我该怎么做才能使触摸/滚动事件独立地作用于两个孩子/兄弟姐妹?
这有点棘手,但我最终弄清楚了。问题本质上是,一旦通过视图(深度优先)进行命中测试,经过命中测试的视图后面或周围的其他视图将停止接收触摸。
诀窍是在所有其他内容之前添加另一个虚拟UIView
,以协调和合并所有触摸。然后从每个.panGestureRecognizer
/UIScrollView
/ UICollectionView
子视图控制器中抓取UITableView
,并将它们添加到此虚拟视图控制器中。
现在,无论视图层次结构中的何处开始滚动并响应触摸,所有滚动列表都无需摆弄hitTest
或子类。
[为了进一步优化哪个滚动视图首先在触摸时做出反应,您可以添加另一个UIPanGestureRecognizer
,然后执行类似.require(toFail: myNewPanGesture)
的操作,以及实现此手势失败方式和时间的实现。这样,您可以控制要首先滚动的可滚动内容。