如何为UICollectionViewCell内的子视图添加手势识别器且不触发cell选中事件
问题原因及修复方案
你遇到的是子视图自定义手势和UICollectionViewCell自带的选中手势的冲突问题,系统默认会优先触发cell的选中回调,不会将点击事件传递给你添加在子视图上的手势,同时你的代码也缺少手势冲突的相关配置。
具体问题点
- 未给自定义手势设置
UIGestureRecognizerDelegate代理,无法处理手势间的优先级和冲突规则 - 未开启手势的拦截属性,点击事件会继续向上传递给cell,触发cell的选中回调
- (附加编译问题)你定义的
setup方法包含currentUserId参数,但调用时没有传入对应参数,会导致编译报错
修复步骤
1. 让Cell类遵守手势代理协议
修改类声明,添加UIGestureRecognizerDelegate遵守:
class RealTimePostCollectionViewCell: UICollectionViewCell, UIGestureRecognizerDelegate { // 原有代码保持不变 }
2. 修改手势初始化配置
调整setupGestureRecognizers方法,添加代理配置和事件拦截属性:
fileprivate func setupGestureRecognizers() { if linkPreviewView.gestureRecognizers?.isEmpty ?? true { let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(linkPreviewViewWasPressed)) // 添加以下两行配置 tapGestureRecognizer.delegate = self tapGestureRecognizer.cancelsTouchesInView = true linkPreviewView.addGestureRecognizer(tapGestureRecognizer) linkPreviewView.isUserInteractionEnabled = true } }
3. 实现手势冲突处理代理方法
在Cell类中添加以下代理方法,设置手势优先级:
// 禁止自定义手势和cell选中手势同时触发 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { if gestureRecognizer.view == linkPreviewView { // 只要是点击linkPreviewView的手势,都不和上层的cell手势共存 return false } return true } // 可选:配置自定义手势优先级高于cell的选中手势,进一步确保点击事件被正确拦截 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool { return gestureRecognizer.view == linkPreviewView }
4. 修复编译问题
调整create方法中调用setup的代码,传入缺失的currentUserId参数,或者根据你的业务逻辑调整setup方法的参数定义。
内容的提问来源于stack exchange,提问作者Sotiris Kaniras
相关产品推荐
相关产品推荐

