I have a very basic view that only shows a TextField
:
struct ContentView: View {
@StateObject var viewModel = ViewModel()
var body: some View {
TextField("Enter a string...", text: $viewModel.string)
}
}
The TextField
's text is bound to a string
property on the view model:
class ViewModel: ObservableObject {
@Published var string: String = "" {
didSet {
print("didSet string:", string)
}
}
}
I added a didSet
property observer to perform a custom action whenever the string changes. For this simple example, I only print a string on the console.
When I run this code and enter the string "123" into the text field, this is the output I get:
didSet string: 1
didSet string: 1
didSet string: 12
didSet string: 12
didSet string: 123
didSet string: 123
Why?
Why is the didSet
closure called twice for each character I type?
(I would expect it to be called once for each character.)
Is there anything wrong with the code or is this expected behavior somehow? 🤔
I’m seeing this issue on Xcode 14.2 RC and iOS 16.2 RC, but weirdly what fixes it is adding a .textFieldStyle(.plain)
or .textFieldStyle(.roundedBorder)
.
I’m really not sure why having no textFieldStyle would affect this, but the binding calls set:{} twice when I have no textFieldStyle set, and as soon as I add one of those, it behaves normally and only calls set:{} once at a time.
I hope this helps someone!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With