首页 > 解决方案 > UICollectionView 在单独的子视图控制器中的 UITableView 之上

问题描述

我的视图层次结构如下。

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只是一个带有两个孩子的容器视图控制器。我该怎么做才能让触摸/滚动事件独立地在两个孩子/兄弟姐妹之间工作?

标签: swiftuitableviewuicollectionviewuigesturerecognizer

解决方案


这有点棘手,但我最终想通了。问题本质上是,一旦一个视图(深度优先)通过了命中测试,命中测试视图后面或周围的其他视图将停止接收触摸。

诀窍是在所有其他内容之前添加另一个虚拟对象UIView以编排和合并所有触摸。然后.panGestureRecognizer从每个UIScrollView//子视图控制器中获取UICollectionViewUITableView并将它们添加到这个虚拟视图控制器中。

现在,无论视图层次结构中的哪个位置开始滚动并响应触摸,所有可滚动列表都无需摆弄hitTest或子类化。

要进一步细化哪个滚动视图首先对触摸做出反应,您可以添加另一个UIPanGestureRecognizer,然后执行类似的操作.require(toFail: myNewPanGesture)以及您希望此手势如何以及何时失败的实现。通过这种方式,您可以控制要首先滚动的可滚动内容。


推荐阅读