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

如何从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.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:13:54