Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding ViewModel and TextFields with SwiftUI

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
like image 373
MatterGoal Avatar asked Jan 02 '20 15:01

MatterGoal


People also ask

Can I use binding in ViewModel SwiftUI?

A ViewModel provides a binding to the properties of its model data, and a SwiftUI view automatically updates when that data changes. Neat!

How do I use binding in SwiftUI?

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.

What is binding in Xcode?

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.


1 Answers

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()
    }
}
like image 53
Satyam Avatar answered Sep 25 '22 10:09

Satyam