Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Observe changes on SwiftUI TextField

I am playing around with Swift UI. I created a table view (a List) containing all my desired elements. Also the TextField change is working when pressing enter on the keyboard. Nice to build so fast a table view ;).

But now I want to track every change on the textfield. Every time user enter another text I want to send a request which triggers a search.

How could this be done in my code? I read also this documentation here https://developer.apple.com/documentation/combine/receiving_and_handling_events_with_combine

I don't now how to use it in my struct.

The proposed solution here TextField changes in SwiftUI does not work (anymore)

I would be thankful for every hint and every idea you can share with me. I am looking for hours for a solution :(.

My code looks like this:

import Foundation
import SwiftUI

struct MyListView: View {
    @ObservedObject var viewModel: MyViewModel

    @State private var query = ""

    var body: some View {

        NavigationView {
            List {
                // how to listen for changes here?
                // if I add onEditingChange here, Get the value only after the user finish search (by pressing enter on the keyboard)
                TextField(String.localizedString(forKey: "search_bar_hint"), text: self.$query) {
                    self.fetchListing()
                } 

                ForEach(viewModel.myArray, id: \.id) { arrayObject in
                    MyRow(arrayObj: arrayObject)
                }
            }
            .navigationBarTitle(navigationBarTitle())
        }
        .onAppear(perform: fetchListing)
    }

    private func fetchListing() {
        query.isEmpty ? viewModel.fetchRequest(for: nil) : viewModel.fetchRequest(for: query)
    }

    private func navigationBarTitle() -> String {
        return query.isEmpty ? String.localizedString(forKey: "my_title") : query
    }
}
like image 252
rb90 Avatar asked Nov 25 '19 20:11

rb90


People also ask

How can I tell if TextField is edited?

Ctrl + Click on the textfield in interface builder. Drag from EditingChanged to inside your view controller class in the assistant view. Name your function ("textDidChange" for example) and click connect.

How do I update TextField in SwiftUI?

To fix that all you need to do is set a style for your TextField with the . textFieldStyle modifier. Now you should see a rounded border around your text field! You can find a list of all of the available text field styles in Apple's documentation here.

What is onChange in SwiftUI?

onChange(of:perform:)Adds a modifier for this view that fires an action when a specific value changes.

What is onCommit?

onCommit. An action to perform when the user performs an action (for example, when the user presses the Return key) while the text field has focus.


1 Answers

A simple custom binding is a good start for this task:

struct ContentView: View {
    @State private var query = ""

    var body: some View {

        let binding = Binding<String>(
            get: { self.query },
            set: { self.query = $0; self.textFieldChanged($0) }
        )

        return NavigationView {
            List {
                TextField("Text", text: binding)
            }
        }
    }

    private func textFieldChanged(_ text: String) { print(text) }
}

It is tested and working

like image 156
Mojtaba Hosseini Avatar answered Nov 01 '22 19:11

Mojtaba Hosseini