Reputation: 63
The same issue exists in Xcode beta 5 . Example code to illustrate the problem listed below :
struct ContentView: View {
@State var someText = "Change me!"
@State var someNumber = 123.0
var body: some View {
Form {
// The entire View is re-rendered after each character is typed
TextField("Text", text: $someText,
onEditingChanged: { edit in
print("onEditingChanged executed!")
},
onCommit: {
print("onCommit executed!")
}
)
// When you enter a Double value, the View is not re-rendered until you hit Return
TextField("Number", value: $someNumber, formatter: NumberFormatter())
Spacer()
Text("text: \(self.someText), number: \(self.someNumber)")
}
}
}
Upvotes: 4
Views: 2222
Reputation: 46
SwiftUI View
s will be recreated each time any of their @ObservedObjects
change or any time their @State
changes.
You are passing a two-way binding of the View
's @State
to the TextField
. The TextField
updates the value of this two-way binding each time its input value changes. This will update the @State
of the View
and thus the View
will be recreated.
I don't think you need to avoid recreating the View
to get the effect you want. Recreating View
s is the backbone of SwiftUI.
You can add an additional @State
property, maybe presentedText
, which you update to the value of someText
inside of onEditingChanged
.
For example (only changed for "text"):
struct ContentView: View {
@State var someText = "Change me!"
@State var someNumber = 123.0
@State var presentedText = someText
var body: some View {
Form {
// The entire View is re-rendered after each character is typed
TextField("Text", text: $someText,
onEditingChanged: { edit in
print("onEditingChanged executed!")
self.presentedText = someText
},
onCommit: {
print("onCommit executed!")
}
)
// When you enter a Double value, the View is not re-rendered until you hit Return
TextField("Number", value: $someNumber, formatter: NumberFormatter())
Spacer()
Text("text: \(self.presentedText), number: \(self.someNumber)")
}
}
}
Upvotes: 1