iOS开发:点击子/父视图区域时收起键盘的替代实现方案
优化方案:点击外部收起键盘(无冗余实现)
嘿,我来给你几个简洁的优化方案,帮你去掉冗余代码,完美解决点击外部(不管是父VC还是子VC的空白区域)收起键盘的问题:
方法1:利用原生事件传递(最简)
只需要在父视图控制器里重写touchesBegan方法就行,不用给子VC加任何额外代码:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesBegan(touches, with: event) // 让当前所有第一响应者 resign,也就是收起键盘 view.endEditing(true) }
⚠️ 注意:如果你的子VC重写了touchesBegan,一定要记得调用super.touchesBegan(touches, with: event),这样点击事件才能向上传递到父VC,这个方法才能生效。
如果你的页面有很多可交互控件(比如按钮、TableView),这些控件会优先拦截点击事件,导致touchesBegan无法触发,这时候用下面的方法更靠谱:
方法2:全局点击手势(兼容所有交互场景)
在父VC的viewDidLoad里添加一个全局的点击手势,设置不阻止其他控件的交互,这样既能捕获空白区域的点击,又不影响按钮、列表这些控件的正常使用:
override func viewDidLoad() { super.viewDidLoad() let tapToDismiss = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard)) // 关键设置:不让手势拦截其他控件的点击事件 tapToDismiss.cancelsTouchesInView = false view.addGestureRecognizer(tapToDismiss) } @objc private func dismissKeyboard() { view.endEditing(true) }
这个方案只需要在父VC里实现一次,子VC完全不用管,自动覆盖父VC和子VC的空白区域,彻底避免冗余代码。
方法3:全局统一处理(适合全APP场景)
如果整个APP都需要点击空白收起键盘的逻辑,可以在AppDelegate里注册全局响应,一劳永逸:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 全局注册:点击空白区域时,让所有第一响应者 resign UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) return true }
这个方法会让APP内任何地方的空白点击都触发收起键盘,适合统一风格的APP。
为什么这些方案比你的现有实现更简洁?
- 不需要在父VC和子VC里分别写重复逻辑,只需要一个地方实现
- 利用UIKit的事件传递机制或者全局手势,自动覆盖所有需要的区域,不用手动给两个VC加监听
内容的提问来源于stack exchange,提问作者LC84
相关产品推荐
相关产品推荐

