如何让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
相关产品推荐
相关产品推荐

