Reputation: 449
I am building some basic form functionality in my app at the moment and I am having trouble with TextFields not changing the value in the relevant binded variable when tapping another TextField or pressing "Done" in Edit Mode.
@Binding var jobDetails: JobDetails
@Environment(\.colorScheme) var colorScheme: ColorScheme
...
var body: some View {
...
HStack {
Text("Hourly Rate")
Spacer()
TextField("", value: $jobDetails.hourlyRateBasic, formatter: TextFormatters().currencyFormatter())
.keyboardType(.asciiCapableNumberPad)
.multilineTextAlignment(.trailing)
...
In the iOS simulator, the field only seems to update when I physically hit the return key on my keyboard after typing in a new value (not the soft keyboard in the simulator). I would like the TextField to commit it's change to jobDetails.hourlyRateBasic
when tapping another TextField or pressing "Done" to exit edit mode.
It seems that onEditingChanged
fires when I tap another TextField, but I don't know how to leverage that into changing the jobDetails
with the new value.
Upvotes: 14
Views: 3694
Reputation: 258345
This is already fixed. Tested with Xcode 13.3 / iOS 15.4
struct TestView: View {
@State private var value1 = 1.0
@State private var text = ""
private var currencyFormatter: NumberFormatter = {
var nf = NumberFormatter()
nf.numberStyle = .currency
return nf
}()
var body: some View {
VStack {
HStack {
Text("Hourly Rate [\(value1)]")
Spacer()
TextField("", value: $value1, formatter: currencyFormatter)
.keyboardType(.asciiCapableNumberPad)
.multilineTextAlignment(.trailing)
}
HStack {
Text("Other")
Spacer()
TextField("Enter something", text: $text)
}
}
}
}
Upvotes: 0
Reputation: 954
This is typical behavior of TextField in SwiftUI. Following is an example of it and alternative method to make TextField more responsive while typing.
import SwiftUI
struct ContentView: View {
@State private var text: String = "0"
@State private var num: Int = 0
private var resultString: String {
if let num = Int(self.text) {
return String(num*num)
}
return "0"
}
private var resultInt: Int {
return self.num*self.num
}
var body: some View {
VStack {
VStack(alignment:.leading) {
Text("Input number as String")
TextField("String Number",text: self.$text)
.textFieldStyle(RoundedBorderTextFieldStyle())
Text("Input number as Int")
TextField("Int Number", value: self.$num, formatter: NumberFormatter())
.textFieldStyle(RoundedBorderTextFieldStyle())
}
Spacer()
Text("From String")
Text("Square of \(self.text) is \(self.resultString)") .font(.title)
Spacer()
Text("From Int")
Text("Square of \(self.num) is \(self.resultInt)") .font(.title)
Spacer()
}.padding()
}
}
Upvotes: 1