UITapGestureRecognizer未触发求助:点击视图控制器无响应
问题排查与解决思路
我来帮你分析下为什么点击黑视图时dismissMenu没被调用,核心问题和解决步骤如下:
1. 最关键的问题:sourceMenu实例被提前释放了
你在sourceButton方法里是这么写的:
@IBAction func sourceButton(_ sender: Any) { let menu = sourceMenu() menu.openMenu() }
这里的menu是方法内的局部变量,当sourceButton方法执行完毕后,ARC(自动引用计数)会立刻释放这个sourceMenu实例——因为没有任何强引用持有它。而你给blackView添加的手势识别器,它的target是这个已经被释放的实例,所以点击手势触发时,找不到对应的对象来调用dismissMenu方法。
解决方法:在你的视图控制器中声明一个属性来强引用sourceMenu实例:
// 假设你的视图控制器叫 ViewController class ViewController: UIViewController { // 用属性持有menu实例,避免被提前释放 private var menuInstance: sourceMenu? @IBAction func sourceButton(_ sender: Any) { menuInstance = sourceMenu() menuInstance?.openMenu() } }
2. 额外的细节优化(避免后续问题)
解决了生命周期问题后,还有几个小细节可以完善:
- 确保视图允许用户交互:虽然
UIView默认isUserInteractionEnabled是true,但显式设置可以避免意外:public func openMenu(){ if let window = UIApplication.shared.windows.filter({ $0.isKeyWindow }).first { blackView.frame = window.frame blackView.backgroundColor = UIColor(white: 0, alpha: 0.5) // 显式开启交互 blackView.isUserInteractionEnabled = true blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.dismissMenu))) window.addSubview(blackView) UIView.animate(withDuration: 0.5) { self.blackView.alpha = 1 } } } - 动画结束后移除视图:当前的
dismissMenu只是把alpha设为0,但视图还留在window的层级里,下次打开会重复添加。可以在动画完成的回调里移除视图:@objc public func dismissMenu(){ UIView.animate(withDuration: 0.5, animations: { self.blackView.alpha = 0 }) { [weak self] _ in // 用weak self避免循环引用 self?.blackView.removeFromSuperview() // 如果不需要保留menu实例,可以让控制器的menuInstance置空 // self?.menuInstance = nil } }
先解决第一个核心的生命周期问题,应该就能让dismissMenu正常触发了,再配合细节优化让整个菜单逻辑更健壮。
内容的提问来源于stack exchange,提问作者Charles Xavier
相关产品推荐
相关产品推荐

