如何收起UISearchBar键盘且不影响其他功能的正常使用?
问题原因
你给父视图添加的全局UITapGestureRecognizer默认会优先拦截所有点击事件,当你点击UITableViewCell时,事件会被该手势先捕获消费,不会继续向下传递给UITableView的事件处理体系,因此didSelectRowAt方法无法触发。
解决方案
方案1:通过手势代理过滤点击区域(推荐)
让当前控制器遵守UIGestureRecognizerDelegate协议,在代理方法中判断点击区域,如果是落在UITableView范围内就放弃手势响应,把事件交还给UITableView处理。
修改后的完整代码如下:
// 首先遵守UIGestureRecognizerDelegate协议 class YourViewController: UIViewController, UIGestureRecognizerDelegate { @IBOutlet weak var searchbar: UISearchBar! @IBOutlet weak var yourTableView: UITableView! // 替换为你自己的tableView变量名 override func viewDidLoad() { super.viewDidLoad() let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap)) tap.delegate = self // 给手势设置代理 view.addGestureRecognizer(tap) } @objc func handleTap() { searchbar.resignFirstResponder() } // 实现手势代理方法,过滤不需要响应手势的区域 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { // 点击区域落在tableView内时,不响应该手势 if touch.view?.isDescendant(of: yourTableView) == true { return false } return true } }
方案2:设置手势不拦截下层事件
如果不需要精准控制区域,也可以直接修改手势的cancelsTouchesInView属性为false,手势识别后不会截断事件,会继续传递给下层视图,同时实现收起键盘和触发cell点击的效果:
override func viewDidLoad() { super.viewDidLoad() let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap)) tap.cancelsTouchesInView = false // 添加这行配置 view.addGestureRecognizer(tap) } @objc func handleTap() { searchbar.resignFirstResponder() }
内容的提问来源于stack exchange,提问作者Ahana Chakraborty
相关产品推荐
相关产品推荐

