1

我有一个 TextField 作为搜索框。我想让它自动搜索,即每当我在 TextField 中输入一个字母时,我应该不按回车就得到结果。这是我的代码:

TextField("Search", text: $searchText, 
    onEditingChanged: {
        isEditing in
        print("isEditing")
        //my method to fetch result
    }, onCommit: {
        print("onCommit")
    })

但它不是那样工作的。在文本字段中输入一个字母后,当我按下回车键时,它首先打印“onCommit”,然后打印“isEditing”。知道如何让它工作吗?

4

3 回答 3

0

在您的情况下,我想使用组合框架的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")
                    }
                })
        }
    }
}
于 2021-06-12T12:48:44.923 回答
0

你可以尝试这样的事情:

TextField("Search", text: Binding(
    get: { searchText },
    set: { newVal in
    searchText = newVal
    // my method to fetch result
}))
于 2021-06-12T11:27:22.510 回答
0

但是,您可以考虑使用这种替代方法来执行搜索框:

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)
    }
}
于 2021-06-12T11:46:55.580 回答