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