You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移除UINavigationBar中UISearchController顶部的多余空白?

问题现象

UISearchController顶部多余空白截图

方案1:修复现有UISearchController的顶部空白

你遇到的空白是iOS导航栏默认给搜索栏预留的适配边距,按以下代码修改即可消除:

override func viewDidLoad() {
    setupSearchBar()
    // 关闭滚动自动隐藏搜索栏的默认行为,避免预留空白位
    navigationItem.hidesSearchBarWhenScrolling = false
    // 不需要大标题模式可关闭,减少额外边距
    navigationController?.navigationBar.prefersLargeTitles = false
    // iOS16+ 直接指定搜索栏内嵌到导航栏,彻底消除顶部空白
    if #available(iOS 16.0, *) {
        navigationItem.preferredSearchBarPlacement = .inline
    }
    navigationController?.navigationBar.layoutIfNeeded()
}

func setupSearchBar(){
    let searchController = UISearchController(searchResultsController: ResultController())
    searchController.searchResultsUpdater = self
    // 避免弹出搜索结果时隐藏导航栏导致布局偏移
    searchController.hidesNavigationBarDuringPresentation = false
    // 自定义搜索框内边距
    searchController.searchBar.searchTextField.contentInset = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
    
    searchController.searchBar.placeholder = "Search"
    navigationItem.searchController = searchController
    navigationController?.navigationBar.backgroundColor = .yellow
}

方案2:用UITextField实现searchResultsController同等效果

如果要完全自定义搜索栏布局,可通过以下逻辑用UITextField实现相同的搜索结果联动效果:

  • 将自定义UITextField设置为navigationItem的titleView
  • 监听TextField的输入状态和内容变化
  • 把结果控制器作为当前页的子控制器,根据输入状态控制显隐和内容刷新

示例代码:

// 提前声明结果控制器属性
private let resultVC = ResultController()

override func viewDidLoad() {
    setupCustomSearchField()
}

func setupCustomSearchField() {
    // 创建自定义搜索框
    let searchField = UITextField(frame: CGRect(x: 0, y: 0, width: view.bounds.width - 80, height: 36))
    searchField.placeholder = "Search"
    searchField.borderStyle = .roundedRect
    searchField.addTarget(self, action: #selector(searchTextChanged(_:)), for: .editingChanged)
    searchField.addTarget(self, action: #selector(searchBeginEditing(_:)), for: .editingDidBegin)
    
    navigationItem.titleView = searchField
    
    // 预先添加结果控制器为子控制器,初始隐藏
    addChild(resultVC)
    view.addSubview(resultVC.view)
    resultVC.view.frame = CGRect(
        x: 0,
        y: navigationController?.navigationBar.frame.maxY ?? 0,
        width: view.bounds.width,
        height: view.bounds.height - (navigationController?.navigationBar.frame.maxY ?? 0)
    )
    resultVC.view.isHidden = true
    resultVC.didMove(toParent: self)
}

@objc private func searchTextChanged(_ sender: UITextField) {
    // 将搜索关键词传给结果控制器,刷新搜索结果
    resultVC.updateSearchKey(sender.text ?? "")
}

@objc private func searchBeginEditing(_ sender: UITextField) {
    // 开始输入时显示结果页
    resultVC.view.isHidden = false
}

// 可在点击取消/空白处调用该方法隐藏结果页
private func dismissSearchResult() {
    view.endEditing(true)
    resultVC.view.isHidden = true
}

内容的提问来源于stack exchange,提问作者someone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 05:27:03