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

iOS:为父视图添加Tap手势后,UIControl子类触摸事件不触发

问题原因与解决方案

当父视图添加UITapGestureRecognizer后,默认情况下手势识别器会拦截触摸事件,取消事件向子视图层级的传递(cancelsTouchesInView默认值为true),导致你的CustomControl无法接收到触摸事件。

下面提供两种可行的解决方法:

方法一:允许事件继续传递给子视图

修改手势识别器的cancelsTouchesInView属性为false,这样手势识别完成后,触摸事件仍会传递给子视图的UIControl,两者的事件都会被触发:

override func viewDidLoad() {
    super.viewDidLoad()
    
    customControl.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)
    
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapOnView(_:)))
    tapGesture.cancelsTouchesInView = false // 关键设置
    view.addGestureRecognizer(tapGesture)
}

方法二:让手势跳过CustomControl的触摸

通过手势代理,判断触摸点是否落在CustomControl范围内,若是则不让手势处理该触摸,确保CustomControl的事件优先响应:

  1. 让ViewController遵循UIGestureRecognizerDelegate协议
  2. 设置手势的代理为当前控制器
  3. 实现shouldReceiveTouch方法过滤触摸事件
class ViewController: UIViewController, UIGestureRecognizerDelegate {
    @IBOutlet weak var customControl: CustomControl!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        customControl.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)
        
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapOnView(_:)))
        tapGesture.delegate = self // 设置代理
        view.addGestureRecognizer(tapGesture)
    }
    
    // 过滤CustomControl范围内的触摸
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        return !touch.view!.isDescendant(of: customControl)
    }
    
    @objc func didTap(_ sender: Any) {
        print("CustomControl 被点击")
    }
    
    @objc func didTapOnView(_ sender: UITapGestureRecognizer) {
        print("父视图被点击")
    }
}

两种方法的区别

  • 方法一:点击CustomControl时,同时触发它的touchUpInside事件和父视图的Tap手势
  • 方法二:点击CustomControl时,仅触发它自己的事件,父视图手势不响应;点击其他区域时触发父视图手势

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 22:12:10