[SUI] 搜索栏
发布: (2026年2月3日 GMT+8 06:02)
4 min read
原文: Dev.to
Source: Dev.to
(看起来您只提供了来源链接,没有提供需要翻译的正文内容。请提供要翻译的文本,我将为您翻译成简体中文。)
NavigationStack 中的搜索栏
NavigationStack 可以通过 searchable 修饰符添加搜索栏。
它的签名如下:
searchable(
text: Binding,
tokens: Binding? = nil,
suggestedTokens: [Token]? = nil,
placement: SearchFieldPlacement = .automatic,
prompt: String? = nil,
token: () -> TokenView? = { nil }
)
- text:用户输入的文本。
- tokens:用于跟踪已显示的 token。
- suggestedTokens:建议的 token 列表。
- placement:搜索栏的位置(
automatic、navigationBarDrawer、sidebar、toolbar等)。 - prompt:占位符文字。
- token:用于显示 token 的视图。
基本使用
struct Person: Identifiable {
let id = UUID()
let name: String
}
private let people: [Person] = [
.init(name: "David Goyes"),
.init(name: "Midoriya Izuku"),
.init(name: "Tanjiro Kamado"),
.init(name: "David Beckham"),
]
struct ContentView: View {
@State private var searchText: String = ""
private var filteredPeople: [Person] {
if searchText.isEmpty {
people
} else {
people.filter { $0.name.localizedStandardContains(searchText) }
}
}
var body: some View {
NavigationStack {
List(filteredPeople) { person in
Text(person.name)
}
.navigationTitle("Personas")
.searchable(text: $searchText, prompt: "¿A quién busca?")
}
}
}
在 iOS 26 中,默认情况下,搜索栏位于底部(相当于
toolbar)。当它成为 first responder 时,会显示在键盘上方。
使用 onChange 更新列表
如果希望存储过滤后的结果,需要手动更新它:
struct ContentView: View {
@State private var searchText: String = ""
@State private var filteredPeople: [Person] = []
var body: some View {
NavigationStack {
List(filteredPeople) { person in
Text(person.name)
}
.navigationTitle("Personas")
.searchable(text: $searchText, prompt: "¿A quién busca?")
.onChange(of: searchText, initial: true) {
filterPeople()
}
}
}
private func filterPeople() {
filteredPeople = searchText.isEmpty
? people
: people.filter { $0.name.localizedStandardContains(searchText) }
}
}
搜索栏的位置
automatic/toolbar:始终显示在底部工具栏。navigationBarDrawer:向上滚动列表时隐藏,向下滚动时重新出现。
要在导航栏中始终显示它:
struct ContentView: View {
@State private var searchText: String = ""
private var filteredPeople: [Person] {
if searchText.isEmpty {
people
} else {
people.filter { $0.name.localizedStandardContains(searchText) }
}
}
var body: some View {
NavigationStack {
List(filteredPeople) { person in
Text(person.name)
}
.navigationTitle("Personas")
.searchable(
text: $searchText,
placement: .navigationBarDrawer(displayMode: .always),
prompt: "¿A quién busca?"
)
}
}
}
使用 searchFocused 进行编程式聚焦
可以通过 searchFocused(_:) 和 @FocusState 来控制搜索栏的焦点:
struct ContentView: View {
@State private var searchText: String = ""
@FocusState private var isFocused: Bool // <-- 栏目的焦点
private var filteredPeople: [Person] {
if searchText.isEmpty {
people
} else {
people.filter { $0.name.localizedStandardContains(searchText) }
}
}
var body: some View {
NavigationStack {
List(filteredPeople) { person in
Text(person.name)
}
.navigationTitle("Personas")
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("Buscar", systemImage: "magnifyingglass") {
isFocused = true // 聚焦搜索栏
}
}
}
.searchable(
text: $searchText,
placement: .navigationBarDrawer(displayMode: .automatic),
prompt: "¿A quién busca?"
)
.searchFocused($isFocused) // 控制焦点
}
}
}
toolbar 中的 “Buscar” 按钮将 isFocused 设置为 true,这会显示键盘并将光标放在搜索栏中。