如何从UINavigationItem关闭UISearchController?取消按钮无效问题
解决UISearchBar取消按钮无法关闭的问题
我来帮你排查这个问题!点击搜索栏的取消按钮没反应,通常是因为没正确配置UISearchController的代理逻辑,或者导航栏的布局恢复逻辑没做好。咱们一步步来修正:
1. 先确保遵守必要的协议
让你的ViewController同时遵守UISearchControllerDelegate和UISearchBarDelegate协议,这样才能接收到取消按钮的回调事件:
class YourViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UISearchControllerDelegate, UISearchBarDelegate { // 你的现有代码 }
2. 正确初始化并配置UISearchController
不要空初始化UISearchController,要合理配置属性并绑定代理,同时保存原始导航栏状态方便后续恢复:
var searchController = UISearchController(searchResultsController: nil) // 保存原始导航栏按钮,用于取消搜索后恢复 private var originalNavButtons: [UIBarButtonItem]? override func viewDidLoad() { super.viewDidLoad() // 配置搜索控制器核心属性 searchController.searchBar.delegate = self searchController.delegate = self // 如果不想隐藏导航栏,设置为false searchController.hidesNavigationBarDuringPresentation = false // 避免搜索控制器影响其他页面的展示 definesPresentationContext = true // 确保取消按钮显示 searchController.searchBar.showsCancelButton = true // 保存原始导航栏按钮 originalNavButtons = navigationItem.rightBarButtonItems }
3. 实现取消按钮的回调逻辑
在UISearchBarDelegate的回调方法里,手动恢复导航栏状态并收起搜索栏:
// 假设这是你点击导航栏按钮显示搜索栏的方法 @objc func toggleSearchBar() { // 将搜索栏设置为导航栏的titleView navigationItem.titleView = searchController.searchBar // 隐藏原来的导航按钮 navigationItem.rightBarButtonItems = nil // 自动唤起键盘 searchController.searchBar.becomeFirstResponder() } // 取消按钮点击的回调 func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { // 收起键盘 searchBar.resignFirstResponder() // 清空搜索内容 searchBar.text = "" // 恢复导航栏原始状态 navigationItem.titleView = nil navigationItem.title = "你的页面标题" // 替换成你原来的标题 navigationItem.rightBarButtonItems = originalNavButtons }
额外排查点
- 如果你是用iOS 11+的
navigationItem.searchController属性来设置搜索控制器,取消按钮的关闭逻辑会更自动,但如果是手动把searchBar作为titleView添加的,就必须手动处理恢复逻辑; - 检查是否有其他代码干扰了导航栏的布局,比如自定义导航栏的子类可能会拦截事件;
- 确认
searchBar.showsCancelButton是否为true,否则取消按钮根本不会显示。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

