Swift:UISearchController的SearchBar失焦后位置偏移Bug
解决UISearchBar作为TableView表头失焦后错位的问题
我之前开发时也碰到过完全一样的情况!这种搜索栏聚焦再失焦后重叠单元格的问题,大多是UISearchController和TableView的布局交互没处理好,给你几个亲测有效的解决思路:
方法1:禁止搜索时隐藏导航栏
如果你的页面带有导航栏,UISearchController默认会在聚焦时隐藏导航栏,恢复时很容易引发布局偏移。直接关闭这个行为就能避免大部分问题:
override func viewDidLoad() { super.viewDidLoad() let searchController = UISearchController(searchResultsController: nil) searchController.searchResultsUpdater = self searchController.obscuresBackgroundDuringPresentation = false // 关键:关闭导航栏自动隐藏逻辑 searchController.hidesNavigationBarDuringPresentation = false tableView.tableHeaderView = searchController.searchBar // 确保TableView自动适配安全区域和导航栏高度 tableView.contentInsetAdjustmentBehavior = .automatic }
方法2:手动强制更新表头Frame
有时候搜索栏失焦后,自身的固有高度没有正确同步到TableView表头的frame里,我们可以在搜索结束时手动刷新布局:
首先让ViewController遵守UISearchBarDelegate,然后实现代理方法:
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) { // 延迟执行,确保系统自身布局完成后再调整 DispatchQueue.main.async { guard let headerView = self.tableView.tableHeaderView else { return } // 用搜索栏的固有高度重新设置表头frame let newFrame = CGRect( x: headerView.frame.origin.x, y: headerView.frame.origin.y, width: self.tableView.bounds.width, height: headerView.intrinsicContentSize.height ) headerView.frame = newFrame // 重新赋值表头触发TableView更新布局 self.tableView.tableHeaderView = headerView } }
方法3:设置正确的展示上下文(iOS13+)
iOS13之后UISearchController的展示上下文逻辑有调整,设置当前VC为展示上下文可以避免布局混乱:
override func viewDidLoad() { super.viewDidLoad() let searchController = UISearchController(searchResultsController: nil) // 让当前VC负责搜索控制器的展示上下文,避免布局穿透 self.definesPresentationContext = true searchController.searchResultsUpdater = self searchController.obscuresBackgroundDuringPresentation = false tableView.tableHeaderView = searchController.searchBar }
问题根源
这种错位本质上是搜索栏激活时的布局变化(比如导航栏高度变化、搜索栏自身尺寸调整),在失焦后系统没有自动同步TableView表头的布局状态,导致表头的frame和TableView的contentInset不匹配,从而出现重叠。
内容的提问来源于stack exchange,提问作者wastene
相关产品推荐
相关产品推荐

