如何通过Storyboard将UISearchBar配置为UISearchController并实现位置切换?
解决方案
核心结论
完全可以将Storyboard中拖入的UISearchBar(IBOutlet)配置为UISearchController的一部分,实现「点击后移动到顶部、输入时展示筛选结果」的需求——Storyboard没有直接提供UISearchController控件,但通过代码绑定即可实现所有功能。
具体实现步骤
1. 准备UI与关联控件
- 在Storyboard中拖入UISearchBar到视图中央,创建IBOutlet并命名为
centerSearchBar。 - 准备搜索结果展示控制器(比如
UITableViewController),可通过Storyboard创建或代码生成,用于显示筛选后的内容。
2. 代码绑定UISearchController与SearchBar
在视图控制器的viewDidLoad方法中初始化并关联:
// 初始化你的搜索结果控制器(替换成实际的结果控制器类) let resultVC = SearchResultTableViewController() // 创建UISearchController并关联结果控制器 let searchController = UISearchController(searchResultsController: resultVC) // 将Storyboard的SearchBar绑定到searchController searchController.searchBar = self.centerSearchBar // 设置代理监听搜索输入变化 searchController.searchResultsUpdater = self // 关闭搜索时的背景模糊(根据需求调整) searchController.obscuresBackgroundDuringPresentation = false // 移除原SearchBar的父视图,避免重复添加 self.centerSearchBar.removeFromSuperview() // 将searchController的搜索栏添加到视图顶部(若有导航栏可绑定到navigationItem) self.view.addSubview(searchController.searchBar) // 初始隐藏顶部搜索栏,只显示中央的那个 searchController.searchBar.isHidden = true // 保存searchController引用(可声明为类属性) self.searchController = searchController
3. 实现点击后的位置动画
通过UISearchBarDelegate监听搜索栏激活事件,执行移动动画:
extension YourViewController: UISearchBarDelegate { func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) { // 隐藏中央搜索栏 self.centerSearchBar.isHidden = true // 显示顶部搜索栏并执行动画 self.searchController?.searchBar.isHidden = false UIView.animate(withDuration: 0.3) { // 调整到顶部位置,注意安全区域(有导航栏的话y值设为导航栏高度) let topY = self.view.safeAreaInsets.top self.searchController?.searchBar.frame = CGRect( x: 0, y: topY, width: self.view.bounds.width, height: 44 ) } // 激活搜索控制器 self.searchController?.isActive = true } }
4. 搜索结果筛选逻辑
让视图控制器遵守UISearchResultsUpdating协议,实现实时筛选:
extension YourViewController: UISearchResultsUpdating { func updateSearchResults(for searchController: UISearchController) { guard let searchText = searchController.searchBar.text, let resultVC = searchController.searchResultsController as? SearchResultTableViewController else { return } // 执行你的数据筛选逻辑(替换成实际的数据源处理) let filteredData = self.originalData.filter { $0.contains(searchText) } // 将筛选结果传给结果控制器并刷新界面 resultVC.filteredData = filteredData resultVC.tableView.reloadData() } }
5. 取消搜索的恢复逻辑
处理取消按钮事件,将搜索栏移回中央:
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { self.searchController?.isActive = false // 动画恢复中央搜索栏的显示 UIView.animate(withDuration: 0.3) { self.centerSearchBar.center = self.view.center } self.centerSearchBar.isHidden = false self.searchController?.searchBar.isHidden = true // 清空搜索内容 searchBar.text = "" }
注意事项
- 确保结果控制器已正确配置UITableView的数据源与代理,能正常展示数据。
- 若使用导航栏,可将
searchController赋值给navigationItem.searchController,但需调整初始隐藏和动画逻辑适配导航栏布局。 - 动画位置需考虑安全区域(比如刘海屏的顶部内边距),避免布局偏移。
内容的提问来源于stack exchange,提问作者Vandal
相关产品推荐
相关产品推荐

