I am trying to update values of SwiftData model by letting user change string inside a TextField. But the binding variable is overwriting the value in TextField instead of querying and showing the value from SwiftData model. I am using @Query in the view and have a @State variable for TextField for Binding variable, initialised to 0 at its definition. So I see 0 in the TextField. But I want to see the value from SwiftData in the TextField instead. How can I do that?
Trying to connect model in SwiftData with SwiftUI TextField
It's a little unclear without code example but I'm guessing your have something like that
var person: Person // SwiftData model retrieved from a @Query
@State private var text: String = "0"
TextField(person.name, text: self.$text)
This will show "0" since the text field display the content of the value it is binded to. The first argument is used as a placeholder to describe the purpose of this field to the user (and is displayed only when the text
is an empty string which is not the case here).
You have 2 options
- Use a
State
property for the textfield value that you update when the view appears. It will no update yourSwiftData
model when the value changes so you will need to implement a validation/save method
struct PersonForm: View {
var person: Person
@State private var text: String = "0"
var body: some View {
VStack {
Button("Save") {
self.person.name = text
}
Text("Name", text: self.$text)
}
.onAppear {
self.text = self.person.name
}
}
}
- Bind the
SwiftData
model property to the text field. This will update your model directly according to the user input without needing validation. IMHO, this is not the best solution since It can trigger a lot of database updates (even ifSwiftData
batches them) and also view updates if you reference your model in another view,SwiftUI
will ask for redraw at each change the user make inside the text field
struct PersonForm: View {
@Bindable var person: Person
@State private var text: String = "0"
var body: some View {
Text("Name", text: self.$person.name)
}
}
Hope this helps