如何从UIPageViewController的子ViewController中收起键盘?
解决UIPageViewController子控制器点击TableView时收起父控制器键盘的问题
嘿,这个问题我之前也碰到过!给UIPageViewController的容器加点击手势确实会和子控制器的TableView手势冲突——手势识别器会先拦截点击事件,导致tableView(_:didSelectRowAt:)代理方法无法正常触发。不过有几个更直接的方法,能让你在任意位置快速收起键盘,完全不用纠结手势冲突的问题:
方法一:全局一键收起键盘(最便捷)
你可以直接调用UIApplication的sendAction方法,这个方法会遍历整个响应链,找到当前的第一响应者(也就是你的SearchBar)并让它 resign,不管它在哪个控制器里。
在子控制器的tableView(_:didSelectRowAt:)方法里加入这段代码就行:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // 收起键盘 UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) // 你的其他业务逻辑 // ... }
这个方法的好处是不需要关心键盘所属的控制器,在任何地方调用都能生效。
方法二:给UIViewController加通用扩展
如果你希望每个控制器都能方便地调用收起键盘的方法,可以给UIViewController写一个扩展:
extension UIViewController { func dismissKeyboard() { // endEditing(true)会让当前视图层级里的所有第一响应者 resign view.endEditing(true) } }
然后在子控制器的TableView点击代理里直接调用:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { dismissKeyboard() // 你的其他逻辑 // ... }
如果父控制器需要主动收起键盘,也可以直接调用dismissKeyboard(),非常灵活。
为什么不推荐手势方法?
给UIPageViewController的容器加点击手势时,手势识别器的响应优先级会高于TableView的点击事件,导致TableView的didSelectRow代理被拦截。除非你手动调整手势的cancelsTouchesInView属性为false,但这样又可能导致手势和TableView的点击事件同时触发,逻辑会变得混乱,所以还是上面两种方法更靠谱。
内容的提问来源于stack exchange,提问作者Vasilis D.
相关产品推荐
相关产品推荐

