如何让UISearchBar的ScopeBar扩展至导航栏全屏宽度?
解决UISearchBar ScopeBar被导航栏左右按钮遮挡的问题
默认情况下,作为navigationItem.titleView的UISearchBar会被左右侧的BarButtonItem限制宽度,导致ScopeBar无法铺满导航栏全屏。以下是两种可行的解决方法:
方案一:通过AutoLayout约束让SearchBar占满导航栏宽度
直接给SearchBar添加与导航栏边缘对齐的约束,强制它铺满整个导航栏,ScopeBar会自动跟随扩展至全屏宽度:
import UIKit class ResultSearchViewController: UIViewController { @IBOutlet weak var rightBarButton: UIBarButtonItem! @IBOutlet var searchBar: UISearchBar! override func viewDidLoad() { super.viewDidLoad() navigationItem.titleView = searchBar searchBar.showsScopeBar = true // 禁用自动布局转换,添加自定义约束 searchBar.translatesAutoresizingMaskIntoConstraints = false guard let navBar = navigationController?.navigationBar else { return } NSLayoutConstraint.activate([ searchBar.leadingAnchor.constraint(equalTo: navBar.leadingAnchor), searchBar.trailingAnchor.constraint(equalTo: navBar.trailingAnchor), searchBar.topAnchor.constraint(equalTo: navBar.topAnchor), searchBar.bottomAnchor.constraint(equalTo: navBar.bottomAnchor) ]) } }
此方法无需修改返回按钮,SearchBar的输入区域会自动避开左右按钮位置,同时保证ScopeBar铺满全屏。
方案二:自定义返回按钮,彻底释放导航栏宽度
如果方案一的自动调整不符合预期,可隐藏系统默认返回按钮,自定义返回按钮后让SearchBar完全占据导航栏:
import UIKit class ResultSearchViewController: UIViewController { @IBOutlet weak var rightBarButton: UIBarButtonItem! @IBOutlet var searchBar: UISearchBar! override func viewDidLoad() { super.viewDidLoad() // 隐藏系统默认返回按钮 navigationItem.hidesBackButton = true // 创建自定义返回按钮 let backButton = UIButton(type: .system) backButton.setImage(UIImage(systemName: "chevron.left"), for: .normal) backButton.setTitle("返回", for: .normal) backButton.addTarget(self, action: #selector(backToPrevious), for: .touchUpInside) navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backButton) // 设置SearchBar为titleView并启用ScopeBar navigationItem.titleView = searchBar searchBar.showsScopeBar = true // 添加约束让SearchBar占满导航栏 searchBar.translatesAutoresizingMaskIntoConstraints = false guard let navBar = navigationController?.navigationBar else { return } NSLayoutConstraint.activate([ searchBar.leadingAnchor.constraint(equalTo: navBar.leadingAnchor), searchBar.trailingAnchor.constraint(equalTo: navBar.trailingAnchor), searchBar.topAnchor.constraint(equalTo: navBar.topAnchor), searchBar.bottomAnchor.constraint(equalTo: navBar.bottomAnchor) ]) } @objc private func backToPrevious() { navigationController?.popViewController(animated: true) } }
该方法完全控制导航栏布局,确保ScopeBar不会被任何元素遮挡,同时保留返回功能。
内容的提问来源于stack exchange,提问作者haruka
相关产品推荐
相关产品推荐

