harp
harp

Reputation: 185

SwiftUI TextField with formatter broken when built with Xcode 13.3?

It looks like Xcode 13.3 broke the TextField with formatter. In example below the Text should show the value entered in the TextField, which works fine when built with Xcode 13.2.1 (downgraded again to test) but with Xcode 13.3 the TextField does not update its binding value.

struct ContentView: View {

    @State var value: Float?

    let decimalFormatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.maximumFractionDigits = 3
        return formatter
    }()

    var body: some View {
        VStack {
            TextField("some float", value: $value, formatter: decimalFormatter)
                .multilineTextAlignment(.center)
                .keyboardType(.decimalPad)
            Text("Value: \(value != nil ? String(value!) : "nil")")
        }
    }
    
}

Upvotes: 2

Views: 1659

Answers (2)

spnkr
spnkr

Reputation: 1382

Corrected code sample, using the method from @harp's answer. This only works on iOS 15+.

TextField("some float",
           value: $value,
           format: .currency(code: "USD"))
   .onChange(of: value) { newValue in
           print ("value is \(newValue)")
       }

Another example of a format. Here using one of the Instance Methods from the Apple docs on FloatingPointFormatStyle:

TextField("some float",
           value: $value,
           format: FloatingPointFormatStyle().decimalSeparator(strategy: .automatic))

More info on this method is in the Apple docs for TextField.init(_:value:format:prompt:)

Upvotes: 2

harp
harp

Reputation: 185

Found a different API that does what I expected with optionals: https://developer.apple.com/documentation/swiftui/textfield/init(_:value:format:prompt:)-6ug7k

TextField("some float", value: $value, format: FloatingPointFormatStyle.number)

Although this does not explain why it previously worked with a Formatter and stopped working with Xcode 13.3, at least this API seems to be specific for optional values.

Limiting fraction digits to 3 also works, it just is not applied instantly during editing but afterwards on focus change.

TextField("some float", value: $value, format: FloatingPointFormatStyle.number
.precision(NumberFormatStyleConfiguration.Precision.fractionLength(0...3)))

Upvotes: 2

Related Questions