I'm looking for the best way to create a bind between textfields
and ViewModel
.
At the moment I'm creating a @State
for each textfield and I'm manually sending the value from textfield to the viewModel properties when needed. I'm pretty sure this is not the best way to go... Is there a way to bind the TextField
with the ViewModel
property?
This is my current code:
struct SigninView: View {
@State var username:String = ""
@State var password:String = ""
var viewModel:SignInViewModel
var body: some View {
VStack(alignment: .leading, spacing: 15.0){
DefaultTextField(placeholder: "username", value: $username)
DefaultTextField(placeholder: "password", value: $password)
Spacer()
FillButton(title:"Sign In"){
///// IS THIS CORRECT?
self.viewModel.email = self.username
self.viewModel.password = self.password
//------------------
self.viewModel.signin()
}
}.padding()
}
}
The view model is something like:
class SignInViewModel:ObservableObject{
var username:String? = nil
var password:String? = nil
A ViewModel provides a binding to the properties of its model data, and a SwiftUI view automatically updates when that data changes. Neat!
In SwiftUI, you can create bindings in 2 ways: With the @Binding property wrapper, which creates a binding, but doesn't store it. With other property wrappers, like @State, which creates a binding, and also stores its value.
A binding connects a property to a source of truth stored elsewhere, instead of storing data directly. For example, a button that toggles between play and pause can create a binding to a property of its parent view using the Binding property wrapper.
I think we can simplify it with below code.
class SignInViewModel: ObservableObject{
@Published var username = ""
@Published var password = ""
}
struct SigninView: View {
@ObservedObject var viewModel = SignInViewModel()
var body: some View {
VStack(alignment: .leading, spacing: 15.0){
TextField("username", text: $viewModel.username)
TextField("password", text: $viewModel.password)
Spacer()
Button("Sign In"){
print("User: \(self.viewModel.username)")
print("Pass: \(self.viewModel.password)")
}
}.padding()
}
}
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