You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在视图中使用UIPanGestureRecognizer时didSelectItemAt未触发

解决UICollectionView didSelectItemAt在多手势下不触发的问题

我来帮你捋捋这个问题——之前做项目时也碰到过类似的坑,你的代码已经走对了第一步,但还有几个关键点没覆盖到:

  • 手势的事件拦截优先级:
    你设置了shouldRecognizeSimultaneouslyWith返回true,允许多个手势同时识别,但UICollectionView的内置点击手势优先级可能比你添加的tap/pan手势低,导致事件被外层手势吞掉了。可以修改代理方法,明确让collectionView的手势优先处理:

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        // 如果另一个手势是collectionView的内置手势,允许同时识别
        return otherGestureRecognizer.view is UICollectionView
    }
    
  • 手势的添加对象错误:
    别把tap/pan手势直接添加到UICollectionView本身上!如果手势加在了collectionView上,它会直接拦截所有触摸事件,collectionView自己的didSelect根本没机会触发。应该把这些手势添加到collectionView的父视图(也就是你的控制器视图)上。

  • 检查交互开关是否开启:
    确认两个地方的userInteractionEnabled都是true:

    • 你的UICollectionView本身
    • CollectionViewCell的实例(自定义cell时很容易不小心把这个设为false)
  • 添加触摸区域过滤:
    可以在手势代理里判断触摸点是否在collectionView范围内,如果是,就让你的tap/pan手势不接收事件,把机会让给collectionView:

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        let touchLocation = touch.location(in: self.view)
        // 触摸点不在collectionView里时,才让手势处理
        return !self.collectionView.frame.contains(touchLocation)
    }
    

你可以先试试把手势移到父视图,再加上触摸区域过滤的代码,这两步大概率能解决问题。

内容的提问来源于stack exchange,提问作者RileyDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:42:36