Home > other >  How to Use Setter of Custom SwiftUI Binding after Value Conversion
How to Use Setter of Custom SwiftUI Binding after Value Conversion

Time:10-29

I have a custom SwiftUI binding where I convert a value before it's rendered in a TextField in my view. I do this because I want to convert the number of minutes (stored as an Int in my database) to one of two time formats (HHMM or #.#).

app.flight is a @Published variable on an ObservableObject in my view model. duration is the Int property of my object, and timeForm is an extension that does the time conversion and returns the appropriate String value.

Here's my binding:

let time = Binding(
  get: {
    app.flight.duration.timeForm //Converts the Int to a String
  },
  set: { $0 } <-- ???
)

...and here is my TextField in my view where I use the time binding:

TextField(timeDisplayHHMM ? "####" : "#.#", text: time, onCommit:{
  print(time.wrappedValue) //<-- Prints the initial value from the binding's getter
})

I need the setter to finish setting the value of time so that when I access it in my onCommit, it has the latest value the user has entered. But as I have it, it's printing the original value from the binding's getter.

How do I make the set statement in my binding pass on the set value so it's ready by the time I use it in onCommit?

CodePudding user response:

you could try something like this approach:

struct ContentView: View {
    @State var timeDisplayHHMM = true
    @State var time = ""
    @State var app_flight_duration: Int = 0  // <-- for testing

    var body: some View {
        VStack {
            Text("time: "   time)
            Text("duration: \(app_flight_duration)")

            TextField(timeDisplayHHMM ? "####" : "#.#",
                      text: Binding(
                        get: { time },
                        set: {
                            time = $0
                            // here convert to int,
                            // you need to do a lot more than this simple example
                            if let theInt = Int($0) {
                                app_flight_duration = theInt // assign to your model
                            }
                        }
                      ),
                      onCommit:{
                print("-----> time "   time   "  app_flight_duration: \(app_flight_duration)")
            })
        }
    }
    
}
  • Related