【问题标题】:Binding ViewModel and TextFields with SwiftUI使用 SwiftUI 绑定 ViewModel 和 TextField
【发布时间】:2020-01-02 15:37:33
【问题描述】:

我正在寻找在textfields 和ViewModel 之间创建绑定的最佳方法。 目前,我正在为每个文本字段创建一个@State,并在需要时将值从文本字段手动发送到 viewModel 属性。我很确定这不是最好的方法......有没有办法将TextField 与ViewModel 属性绑定?

这是我当前的代码:

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()
    }
}

视图模型类似于:

class SignInViewModel:ObservableObject{

    var username:String? = nil
    var password:String? = nil

【问题讨论】:

    标签: ios swiftui combine


    【解决方案1】:

    我想我们可以用下面的代码来简化它。

    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()
        }
    }
    

    【讨论】:

    • 由于观察到的视图模型及其发布的成员从视图发生变化,这不会导致额外的视图更新吗?
    • @giorashc 这里观察者本身的概念是在视图模型发生变化时更新UI,或者在用户键入时将文本字段中的文本放入变量中。
    【解决方案2】:

    这是可能的方法(当然我没有你的自定义视图,所以只是用标准替换,但想法是一样的)。使用 Xcode 11.2/iOS 13.2 测试

    class SignInViewModel: ObservableObject{
    
        @Published var username:String? = nil
        @Published var password:String? = nil
    }
    
    
    struct SigninView: View {
        @ObservedObject var viewModel = SignInViewModel()
    
        var body: some View {
            VStack(alignment: .leading, spacing: 15.0){
    
                TextField("username", text: Binding<String>(
                    get: {self.viewModel.username ?? ""},
                    set: {self.viewModel.username = $0}))
                TextField("password", text: Binding<String>(
                    get: {self.viewModel.password ?? ""},
                    set: {self.viewModel.password = $0}))
    
                Spacer()
    
                Button("Sign In"){
                    print("User: \(self.viewModel.username)")
                    print("Pass: \(self.viewModel.password)")
                }
            }.padding()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-16
      • 1970-01-01
      • 2023-01-10
      相关资源
      最近更新 更多