Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI TextField with formatter not working?

Tags:

swiftui

I'm trying to get a numeric field updated so I'm using a TextField with the formatter: parameter set. It formats the number into the entry field just fine, but does not update the bound value when edited. The TextField works fine (on Strings) without the formatter specified. Is this a bug or am I missing something?

UPDATE: As of Xcode 11 beta 3 it kind of works. Now if you edit the numeric TextField, the bound value is updated after you hit return. The String TextField is still updated after each keypress. I guess they don't want to send the value to be formatted to the formatter with every key press, or maybe there is/will be a modifier for TextField to tell it to do that.

Note that The API has changed slightly; the old TextField init()s are deprecated and a new titleKey String field has been added as the first parameter which appears as placeholder text in the field.

struct TestView : View {    @State var someText = "Change me!"    @State var someNumber = 123.0    var body: some View {        Form {             // Xcode 11 beta 2             // TextField($someText)             // TextField($someNumber, formatter: NumberFormatter())             // Xcode 11 beta 3             TextField("Text", text: $someText)             TextField("Number", value: $someNumber, formatter: NumberFormatter())             Spacer()             // if you change the first TextField value, the change shows up here             // if you change the second (the number),             // it does not *until you hit return*             Text("text: \(self.someText), number: \(self.someNumber)")             // the button does the same, but logs to the console             Button(action: { print("text: \(self.someText), number: \(self.someNumber)")}) {                 Text("Log Values")             }         }     } } 

If you type in the first (String) TextField, the value in the Text view is updated immediately. If you edit the second (Numeric), nothing happens. Similarly tapping the Button shows an updated value for the String, but not the number. I've only tried this in the simulator.

like image 668
KRH Avatar asked Jun 27 '19 23:06

KRH


Video Answer


1 Answers

You can use Binding to convert Double<-->String for TextField

struct TestView: View {     @State var someNumber = 123.0      var body: some View {         let someNumberProxy = Binding<String>(             get: { String(format: "%.02f", Double(self.someNumber)) },             set: {                 if let value = NumberFormatter().number(from: $0) {                     self.someNumber = value.doubleValue                 }             }         )          return VStack {             TextField("Number", text: someNumberProxy)              Text("number: \(someNumber)")         }       } }  

You can use computed property way to solve this issue. (thanks @ iComputerfreak)

struct TestView: View {     @State var someNumber = 123.0      var someNumberProxy: Binding<String> {         Binding<String>(             get: { String(format: "%.02f", Double(self.someNumber)) },             set: {                 if let value = NumberFormatter().number(from: $0) {                     self.someNumber = value.doubleValue                 }             }         )     }      var body: some View {         VStack {             TextField("Number", text: someNumberProxy)              Text("number: \(someNumber)")         }       } } 
like image 194
Victor Kushnerov Avatar answered Sep 30 '22 21:09

Victor Kushnerov