【问题标题】:AutoComplete search in swiftui not workingswiftui中的自动完成搜索不起作用
【发布时间】:2021-08-29 01:27:27
【问题描述】:

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

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

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

【问题讨论】:

    标签: swiftui swiftui-list swiftui-environment swiftui-form swiftui-texteditor


    【解决方案1】:

    你可以试试这样的:

    TextField("Search", text: Binding(
        get: { searchText },
        set: { newVal in
        searchText = newVal
        // my method to fetch result
    }))
    

    【讨论】:

      【解决方案2】:

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

      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)
          }
      }
      

      【讨论】:

        【解决方案3】:

        在您的情况下,我想使用 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")
                            }
                        })
                }
            }
        }
        

        【讨论】:

        • 感谢 Mahmud。它正在工作,但我也面临一个问题。在 onReceive 的 if 条件内,我正在调用我的方法来获取搜索结果,当我显示时得到结果后, onReceive 中的方法不断调用。
        • 能否请您复制并粘贴代码进行测试。在我的测试中,它可以正常工作。或者您可以以简单的形式分享您的代码,我可以对其进行测试。
        猜你喜欢
        • 1970-01-01
        • 2017-09-16
        • 1970-01-01
        • 1970-01-01
        • 2021-04-26
        • 1970-01-01
        • 2018-12-25
        • 1970-01-01
        • 2021-10-21
        相关资源
        最近更新 更多