TextField("x", value: $y, format: .currency(code: "USD")) Behaves oddly

Hello,

If we have the following code:

import SwiftUI

struct ContentView: View {
	@State private var usdAmount = 0.0

	var body: some View {
		VStack {
			Text("Currency Form")
			Form {
				TextField("Dollar Amount", value: $usdAmount, format: .currency(code: "USD"))	//	1
//				TextField("Dollar Amount", value: $usdAmount, format: .number)					//	2
					.keyboardType(.numberPad)
			}
			Text("usdAmount = \(usdAmount)")
		}
		.padding()
	}
}

When the line marked // 1 is left uncommented (the TF has a .currency() formatter applied) the behaviour of the TF is rather odd.

Upon display it shows US$0.00 Upon editing the value the US$ part remains. So if the user enters US$123 the value is not stored into the usdAmount property.

The User must delete all the existing text and enter e.g. 456.78 and then the value is stored to the usdAmount property.

When Line //1 is commented-out and line //2 is uncommented then the TF behaves correctly because the TF value is just 0 on first display.

Should we not use the .currency() format? Or am I using it wrong?

Thanks.

Answered by Claude31 in 791299022

I would do it with a text format:

struct ContentView: View {
    @State private var usdAmount = 0.0
    @State private var usd = "0"

    var body: some View {
        VStack {
            Text("Currency Form")
            Form {
//                TextField("Dollar Amount", value: $usdAmount, format: .currency(code: "USD"))    //    1
                TextField("Dollar Amount", value: $usdAmount, format: .number)                    //    2
                    .keyboardType(.numberPad)
                TextField("Dollar Amount", text: $usd)                    //    text format
                    .keyboardType(.numberPad)
                    .onTapGesture {
                        usd = ""
                    }
                    .onSubmit {
                        usdAmount = Double(usd) ?? 0.0
                        usd = "$ " + usd
                    }
            }
            Text("usdAmount = \(usdAmount) \(usd)")
        }
        .padding()
    }
}

I would do it with a text format:

struct ContentView: View {
    @State private var usdAmount = 0.0
    @State private var usd = "0"

    var body: some View {
        VStack {
            Text("Currency Form")
            Form {
//                TextField("Dollar Amount", value: $usdAmount, format: .currency(code: "USD"))    //    1
                TextField("Dollar Amount", value: $usdAmount, format: .number)                    //    2
                    .keyboardType(.numberPad)
                TextField("Dollar Amount", text: $usd)                    //    text format
                    .keyboardType(.numberPad)
                    .onTapGesture {
                        usd = ""
                    }
                    .onSubmit {
                        usdAmount = Double(usd) ?? 0.0
                        usd = "$ " + usd
                    }
            }
            Text("usdAmount = \(usdAmount) \(usd)")
        }
        .padding()
    }
}

Thanks. So is .currency() mainly for non-editable formatting?

TextField("x", value: $y, format: .currency(code: "USD")) Behaves oddly
 
 
Q