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

如何让CollectionViewCell内的UITextView点击时触发didSelect方法

原因说明

UITextView 默认开启用户交互,哪怕将 editable 设为 false,它依然会拦截消费触摸事件,导致事件不会向下传递到下层的 UICollectionViewCell,因此无法触发 cell 的 didSelectItemAt 回调。

解决方案

你可以根据自己的业务需求选择以下任意一种方案:

  • 方案1(最简单,无需额外自定义):直接关闭 UITextView 的用户交互
    如果你不需要使用 UITextView 的文本选中、链接点击等自带交互,直接将 isUserInteractionEnabled 设为 false 即可,触摸事件会直接透传给下层 cell:

    yourTextView.isUserInteractionEnabled = false
    

    如果是xib/Storyboard搭建的界面,直接在属性检查器里取消勾选「User Interaction Enabled」即可。

  • 方案2(保留文本选中能力):给UITextView添加点击手势,手动触发cell选中
    如果你需要保留textView的文本选中、复制功能,可给textView添加单击手势,在手势回调中手动调用collectionView的选中方法:

    // 在cell初始化时添加手势
    let tap = UITapGestureRecognizer(target: self, action: #selector(textViewTapped))
    yourTextView.addGestureRecognizer(tap)
    
    // 手势回调
    @objc func textViewTapped() {
        guard let collectionView = superview as? UICollectionView,
              let indexPath = collectionView.indexPath(for: self) else { return }
        collectionView.delegate?.collectionView?(collectionView, didSelectItemAt: indexPath)
    }
    
  • 方案3(自定义textView透传事件):重写触摸事件方法,将点击事件透传给响应链下层
    自定义UITextView子类,重写触摸事件回调,把事件传递给下一个响应者,既保留textView原有交互能力,也能触发cell的选中回调:

    class EventPassThroughTextView: UITextView {
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
            next?.touchesEnded(touches, with: event)
            super.touchesEnded(touches, with: event)
        }
    }
    

    之后把cell里的textView的类改为EventPassThroughTextView即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:15:02