Swift技术问题:添加到KeyWindow的子视图Tap手势无法触发
解决遮罩视图Tap手势未触发的问题
我之前也碰到过这个坑!遮罩显示正常但手势没反应,大概率是这几个常见原因,咱们一个个来排查:
1. 手势的Target/Action未正确绑定
你给出的代码里UITap...部分被截断了,首先得确认手势有没有正确绑定目标和方法。比如完整的手势创建代码应该是这样:
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleBackViewTap)) backView.addGestureRecognizer(tapGesture)
还要确保响应方法能被OC runtime识别,Swift里需要给方法加上@objc标记:
@objc func handleBackViewTap() { // 这里写你的点击逻辑 }
2. 遮罩视图的用户交互被禁用
虽然UIView默认isUserInteractionEnabled是true,但有时候会被误修改或者在某些场景下失效,手动显式设置更稳妥:
backView.isUserInteractionEnabled = true
3. iOS 13+ 后KeyWindow的获取方式失效
从iOS13开始,UIApplication.shared.keyWindow已经被废弃,多场景(比如iPad分屏)下这个方法还可能返回错误的窗口。正确的获取方式应该从活跃场景中提取:
if let window = UIApplication.shared.connectedScenes .filter({$0.activationState == .foregroundActive}) .compactMap({$0 as? UIWindowScene}) .first?.windows .filter({$0.isKeyWindow}).first { backView.frame = window.frame window.addSubview(backView) }
如果还用旧方法,可能你的遮罩根本没加到正确的keyWindow上,自然收不到点击事件。
4. 有其他视图遮挡了遮罩
检查一下你的menuView是不是完全覆盖了backView?如果menuView的frame和遮罩一样大,点击事件会被menuView优先拦截。这种情况要么给menuView设置isUserInteractionEnabled = false(如果不需要它处理交互),要么确保backView在视图层级的最上层。
5. 手势属性或冲突问题
如果手势的cancelsTouchesInView被设为true,或者和其他手势存在冲突,也可能导致不触发。可以调整手势属性:
tapGesture.cancelsTouchesInView = false
如果有多个手势共存,还可以实现UIGestureRecognizerDelegate的方法来处理手势冲突。
先从这几点排查,应该能解决问题!
内容的提问来源于stack exchange,提问作者Bubu
相关产品推荐
相关产品推荐

