问题描述
我有一个 TextField 作为搜索框。我想让它自动搜索,即每当我在 TextField 中输入一个字母时,我应该不用按回车键就能得到结果。这是我的代码:
TextField("Search",text: $searchText,onEditingChanged: {
isEditing in
print("isEditing")
//my method to fetch result
},onCommit: {
print("onCommit")
})
但它不是那样工作的。在文本字段中输入一个字母后,当我按下回车键时,它首先打印“onCommit”,然后打印“isEditing”。知道如何让它工作吗?
解决方法
你可以试试这样的:
TextField("Search",text: Binding(
get: { searchText },set: { newVal in
searchText = newVal
// my method to fetch result
}))
,
但是,您可以考虑使用这种替代方法来创建搜索框:
let langDictionary: [String:String] = [
"af" : "Afrikaans","al" : "Albanian","ar" : "Arabic","az" : "Azerbaijani","bg" : "Bulgarian","ca" : "Catalan","cz" : "Czech","da" : "Danish","de" : "German","el" : "Greek","en" : "English","eu" : "Basque","fa" : "Persian (Farsi)","fi" : "Finnish","fr" : "French","gl" : "Galician","he" : "Hebrew","hi" : "Hindi","hr" : "Croatian","hu" : "Hungarian","id" : "Indonesian","it" : "Italian","ja" : "Japanese","kr" : "Korean","la" : "Latvian","lt" : "Lithuanian","mk" : "Macedonian","no" : "Norwegian","nl" : "Dutch","pl" : "Polish","pt" : "Portuguese","pt_br" : "Portuguese (Brazil)","ro" : "Romanian","ru" : "Russian","se" : "Swedish","sk" : "Slovak","sl" : "Slovenian","es" : "Spanish","sr" : "Serbian","th" : "Thai","tr" : "Turkish","uk" : "Ukrainian","vi" : "Vietnamese","zh_cn" : "Chinese Simplified","zh_tw" : "Chinese Traditional","zu" : "Zulu"]
struct ContentView: View {
@State var searchQuery = ""
@State var langArr = Array(langDictionary.values.sorted {$0 < $1})
var body: some View {
VStack (spacing: 30) {
TextField("Search",text: $searchQuery).padding(10)
.overlay(RoundedRectangle(cornerRadius: 15).stroke(Color.blue,lineWidth: 1))
.foregroundColor(.blue)
ScrollView {
VStack(spacing: 10) {
// move the search system here
ForEach(langArr.filter{self.searchFor($0)}.sorted(by: { $0 < $1 }),id: \.self) { lang in
Text(lang).padding(10)
}
}
}
}.padding(10)
}
private func searchFor(_ txt: String) -> Bool {
return (txt.lowercased(with: .current).hasPrefix(searchQuery.trim().lowercased(with: .current)) || searchQuery.trim().isEmpty)
}
}
,
在您的情况下,我想使用Combine 框架的Just
订阅者。请查看 .onReceive
部分以了解。这是经过测试的代码。 Just
是一个发布者,它只向每个订阅者发出一次输出,然后完成。
因此,当它检测到更改时,它会发布并.onReceiver
捕获该更改。
import SwiftUI
import Combine
struct TestView: View {
@State var searchText: String = ""
var body: some View {
VStack {
TextField("Search",text: $searchText,onEditingChanged: {
isEditing in
print("isEditing")
//my method to fetch result
},onCommit: {
print("onCommit")
})
.onReceive(Just(searchText),perform: { _ in
if searchText.count > 0 {
print("Text entered: \(searchText). Now do whatever you want")
}
})
}
}
}