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

Swift UIKit纯代码实现UISearchController右侧添加按钮

纯代码实现导航栏UISearchController右侧添加自定义按钮

以下方案适配iOS 13+版本,全程纯代码实现,无storyboard/xib依赖,不会出现搜索激活时按钮被遮挡、布局错乱问题。

核心实现思路

  • 用iOS 11之后系统提供的navigationItem.searchController挂载搜索控制器,不要手动把searchBar塞到tableView头部或者导航栏titleView,避免系统布局适配问题
  • 隐藏UISearchBar自带的系统取消按钮,空出右侧导航栏位置放自定义按钮
  • 监听搜索控制器的激活/退出回调,在状态切换时重新挂载自定义按钮,避免系统在搜索态重置导航栏配置导致按钮消失

以下代码以Swift为例,Objective-C开发逻辑完全一致,仅语法写法有区别,核心配置项、代理回调逻辑通用。

核心代码实现

1. 控制器基础定义

import UIKit

class YourViewController: UIViewController, UISearchControllerDelegate {
    // 初始化搜索控制器,传nil代表搜索结果在当前页展示
    private let searchController = UISearchController(searchResultsController: nil)
    // 自定义右侧按钮
    private lazy var customRightBarBtn: UIBarButtonItem = {
        let btn = UIBarButtonItem(
            title: "取消",
            style: .plain,
            target: self,
            action: #selector(rightBarBtnAction)
        )
        btn.tintColor = .systemBlue
        return btn
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupSearchController()
    }
}

2. 搜索控制器基础配置

private func setupSearchController() {
    // 搜索时不蒙层当前页面
    searchController.obscuresBackgroundDuringPresentation = false
    searchController.searchBar.placeholder = "搜索内容"
    // 隐藏系统自带取消按钮,给自定义按钮腾位置
    searchController.searchBar.showsCancelButton = false
    // 绑定搜索代理
    searchController.delegate = self
    
    // 把搜索控制器挂到导航项上
    navigationItem.searchController = searchController
    // 滚动时不隐藏搜索栏,可根据自己业务需求开关
    navigationItem.hidesSearchBarWhenScrolling = false
    // 初始状态设置右侧按钮
    navigationItem.rightBarButtonItem = customRightBarBtn
    
    definesPresentationContext = true
}

3. 搜索状态切换时的按钮适配

// MARK: - UISearchControllerDelegate
func willPresentSearchController(_ searchController: UISearchController) {
    // 搜索即将激活时,重新设置右侧按钮,避免被系统配置覆盖
    navigationItem.rightBarButtonItem = customRightBarBtn
}

func willDismissSearchController(_ searchController: UISearchController) {
    // 搜索即将退出时,重新设置右侧按钮
    navigationItem.rightBarButtonItem = customRightBarBtn
}

// 右侧按钮点击事件
@objc private func rightBarBtnAction() {
    // 这里写自己的业务逻辑,比如退出搜索、跳转其他页面等
    searchController.isActive = false
}

常见踩坑提醒

  • 不要直接把自定义按钮addSubview到UISearchBar上:跨iOS版本会出现位置偏移、点击区域失效、布局错乱问题
  • 不要通过runtime或者遍历子视图修改UISearchBar内部层级:会存在App Store审核风险,且iOS大版本升级后很容易失效
  • 如果需要在搜索激活/非激活状态切换按钮样式,直接在willPresentSearchController和willDismissSearchController回调里修改按钮的title、image属性即可,不需要额外做布局适配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:21:31