2

I have a TextField as search box.I want to make it autosearch i.e whenever i will enter a letter in the TextField, i should get the result without press a enter.Here is my code:

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

But it's not working like that.After entering a letter in the textfield, when i press enter, first it prints "onCommit" and after that it prints "isEditing".Any idea how can i make it work?

Santanu
  • 337
  • 1
  • 3
  • 13

3 Answers3

0

you could try something like this:

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

However you could consider this alternative approach, to do a search box:

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

In your situation, I would like to use the Combine framework's Just subscriber. Please check the .onReceive part to understand. This is a tested code. Just is a publisher that emits an output to each subscriber just once, and then finishes.

So when it detects the change it publishes and .onReceiver capture that changes.

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 Ahsan
  • 1,755
  • 19
  • 18
  • Thanks Mahmud.It is working but i am facing a problem also.Inside the if condition of onReceive, i am calling my method to get the search result and after getting the result when i am showing, the method inside onReceive is calling continuously. – Santanu Jun 16 '21 at 07:18
  • Can you please just copy and paste the code to test. In my test, it's working without any issue. Or you can share your code in simple form, which I can test. – Mahmud Ahsan Jun 17 '21 at 05:47