如何配置CollectionView兼容LNPopupController:保留水平滚动并支持下拉关闭
我之前也碰到过一模一样的情况,问题核心在于你虽然子类化了UICollectionView并实现了手势代理方法,但没有把CollectionView的滚动手势代理绑定到子类实例上,导致那个代理方法根本没被执行。另外我们还可以优化手势识别逻辑,确保水平滚动不受影响的同时,支持垂直拖拽关闭弹窗。
具体解决方案:
完善CollectionView子类,绑定手势代理
你需要在MyCollectionView的初始化方法中,把它自带的滚动手势(panGestureRecognizer)的代理设置为自身,这样手势代理方法才会被系统调用:class MyCollectionView: UICollectionView, UIGestureRecognizerDelegate { override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) { super.init(frame: frame, collectionViewLayout: layout) self.panGestureRecognizer.delegate = self } required init?(coder: NSCoder) { super.init(coder: coder) self.panGestureRecognizer.delegate = self } func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { // 优化逻辑:只在垂直拖拽时允许同时识别手势,不影响水平滚动 guard let panGesture = gestureRecognizer as? UIPanGestureRecognizer else { return false } let velocity = panGesture.velocity(in: self) // 当垂直方向拖拽速度大于水平时,允许弹窗的关闭手势同时工作 return abs(velocity.y) > abs(velocity.x) } }保留原有的CollectionView配置
你之前的setupCollection方法不需要改动,确保scrollDirection = .horizontal和isPagingEnabled = true这些设置正常生效,这样CollectionView的水平滚动功能依然不受影响。
为什么之前的代码无效?
UICollectionView自带的panGestureRecognizer负责处理滚动逻辑,默认情况下它的代理并不是你的子类实例,所以你实现的shouldRecognizeSimultaneouslyWith方法根本不会被触发。只有把这个手势的代理绑定到子类后,才能让系统允许LNPopupController的拖拽关闭手势和CollectionView的滚动手势同时识别。
这样修改后,你在CollectionView区域垂直向下拖拽时就能正常关闭弹窗,水平拖拽时CollectionView依然可以正常滚动,完美解决手势冲突问题~
内容的提问来源于stack exchange,提问作者Adam

