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

SwiftUI中如何自定义.searchable()修饰符生成的搜索栏样式?

SwiftUI中自定义.searchable()搜索栏的外观(字体、形状、背景色)

SwiftUI原生的.searchable()修饰符确实没有直接提供修改字体、形状、背景色的专属API,不过可以通过以下两种方式实现自定义需求:

方法一:通过UIAppearance全局修改UISearchBar样式

利用UIKit的UISearchBar.appearance()可以全局统一设置所有原生搜索栏的样式,适合需要APP内所有搜索栏保持一致风格的场景。

在你的App入口或者目标视图的init方法中添加如下代码:

init() {
    let searchBarAppearance = UISearchBar.appearance()
    
    // 修改搜索栏整体背景色
    searchBarAppearance.backgroundColor = .systemGray6
    
    // 获取并修改搜索输入框的样式
    if let searchTextField = searchBarAppearance.searchTextField {
        // 输入框背景色
        searchTextField.backgroundColor = .white
        // 输入框圆角
        searchTextField.layer.cornerRadius = 16
        searchTextField.clipsToBounds = true
        // 输入框字体
        searchTextField.font = UIFont.systemFont(ofSize: 14, weight: .medium)
        // 占位符文字样式
        searchTextField.attributedPlaceholder = NSAttributedString(
            string: "搜索",
            attributes: [.foregroundColor: UIColor.gray]
        )
    }
}

注意:这种方式是全局生效的,会影响所有使用.searchable()的视图。如果需要单独给某个搜索栏定制样式,更推荐用下面的自定义搜索栏方案。

方法二:完全自定义搜索栏替代原生实现

如果需要更灵活的样式控制(比如不同页面用不同风格的搜索栏),可以自己实现一个搜索栏组件,完全脱离原生.searchable()的限制。

自定义搜索栏组件

struct CustomSearchBar: View {
    @Binding var searchText: String
    var placeholder: String = "搜索"
    
    var body: some View {
        HStack(spacing: 8) {
            // 搜索图标
            Image(systemName: "magnifyingglass")
                .foregroundColor(.gray)
            
            // 输入框
            TextField(placeholder, text: $searchText)
                .font(.system(size: 14, weight: .medium))
                .foregroundColor(.primary)
            
            // 清空按钮
            if !searchText.isEmpty {
                Button(action: { searchText = "" }) {
                    Image(systemName: "xmark.circle.fill")
                        .foregroundColor(.gray)
                }
            }
        }
        .padding(.horizontal, 12)
        .padding(.vertical, 8)
        .background(Color.white)
        .cornerRadius(16)
        .overlay(
            RoundedRectangle(cornerRadius: 16)
                .stroke(Color.gray.opacity(0.2), lineWidth: 1)
        )
    }
}

使用自定义搜索栏

直接在视图中添加该组件,替代原生的.searchable(),并绑定搜索文本即可:

struct ContentView: View {
    @State private var searchText = ""
    // 模拟列表数据
    private let items = ["苹果", "香蕉", "橙子", "葡萄"]
    
    // 过滤后的列表数据
    private var filteredItems: [String] {
        if searchText.isEmpty {
            return items
        } else {
            return items.filter { $0.localizedCaseInsensitiveContains(searchText) }
        }
    }
    
    var body: some View {
        NavigationStack {
            List(filteredItems, id: \.self) { item in
                Text(item)
            }
            .navigationTitle("水果列表")
            // 将自定义搜索栏放在导航栏下方
            .overlay(
                CustomSearchBar(searchText: $searchText)
                    .padding(.horizontal)
                , alignment: .top
            )
            .padding(.top, 8)
        }
    }
}

这种方式可以完全自定义字体、圆角、背景色、图标样式等,还能根据需求添加额外交互逻辑,唯一的缺点是需要自己实现搜索过滤逻辑,不过代码量不大,可控性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:15:53