My question is probably the result of a misunderstanding but I can't figure it out, so here it is:
When using a component like a TextField or any other component requiring a binding as input
TextField(title: StringProtocol, text: Binding<String>)
And a View with a ViewModel, I naturally thought that I could simply pass my ViewModel @Published properties as binding :
class MyViewModel: ObservableObject {
@Published var title: String
@Published var text: String
}
// Now in my view
var body: some View {
TextField(title: myViewModel.title, text: myViewModel.$text)
}
But I obviously can't since the publisher cannot act as binding. From my understanding, only a @State property can act like that but shouldn't all the @State properties live only in the View and not in the view model? Or could I do something like that :
class MyViewModel: ObservableObject {
@Published var title: String
@State var text: String
}
And if I can't, how can I transfer the information to my ViewModel when my text is updated?
You were almost there. You just have to replace myViewModel.$text with $myViewModel.text.
class MyViewModel: ObservableObject {
var title: String = "SwiftUI"
@Published var text: String = ""
}
struct TextFieldView: View {
@ObservedObject var myViewModel: MyViewModel = MyViewModel()
var body: some View {
TextField(myViewModel.title, text: $myViewModel.text)
}
}
TextField expects a Binding (for text parameter) and ObservedObject property wrapper takes care of creating bindings to MyViewModel's properties using dynamic member lookup.
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