【问题标题】:How to bind a function in view model to a custom view in swiftui?如何将视图模型中的函数绑定到swiftui中的自定义视图?
【发布时间】:2021-03-30 01:14:57
【问题描述】:

我有一个自定义文本字段:

struct InputField: View {

    var inputText: Binding<String>
    var title: String
    var placeholder: String
    @State var hasError = false

    var body: some View {
        VStack(spacing: 5.0) {
            HStack {
                Text(title)
                    .font(.subheadline)
                    .fontWeight(.semibold)
                Spacer()
            }
            TextField(placeholder, text: inputText).frame(height: 50).background(Color.white)
                .cornerRadius(5.0)
                .border(hasError ? Color.red : Color.clear, width: 1)

        }
    }
}

我的视图模型是:

class LoginViewModel: ObservableObject {
 
    @Published var username = "" {
        didSet {
            print("username is: \(username)")
        }
    }
     func checkUsernameisValid() -> Bool {
        return username.count < 6
    }
}

以及我的最终登录视图:

@ObservedObject var loginViewModel = LoginViewModel()

var inputFields: some View {
        VStack {
            InputField(inputText: $loginViewModel.username, title: "Username:", placeholder: "  Enter your username", hasError: $loginViewModel.checkUsernameisValid())
            InputField(inputText: $loginViewModel.password, title: "Password:", placeholder: "  Enter your password", hasError: $loginViewModel.checkUsernameisValid())
        }
  }

现在在hasError:$loginViewModel.checkUsernameisValid() 抱怨我无法将函数绑定到状态变量hasError

如何通过仍然使用函数checkUsernameisValid() 更新我的自定义文本字段视图来完成这项工作?

我可以解决这个问题的一种方法是在我的视图模型中使用另一个已发布的变量

@Published var validUsername = false

 func checkUsernameisValid() {
    validUsername = username.count < 6
}

并在我的用户名 var 的 didSet 中继续调用此函数

@Published var username = "" {
    didSet {
        print("username is: \(username)")
        checkUsernameisValid()
    }
}

最终使用新发布的var绑定hasError:

hasError: $loginViewModel.validUsername

我的问题是,这是唯一的方法吗?即使用@published var 进行绑定,我不能直接使用独立函数来做同样的事情,而不是使用越来越多的@Published 变量?

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    试试:

    @ObservedObject var loginViewModel = LoginViewModel()
    
    var inputFields: some View {
            VStack {
                InputField(inputText: $loginViewModel.username, title: "Username:", placeholder: "  Enter your username", hasError: loginViewModel.checkUsernameisValid())
                InputField(inputText: $loginViewModel.password, title: "Password:", placeholder: "  Enter your password", hasError: loginViewModel.checkUsernameisValid())
            }
      }
    

    函数作用于绑定变量的实际值,而不是绑定本身。

    【讨论】:

      【解决方案2】:

      您不需要绑定错误。 InputField 将由 inputText 更新,因此您只需要一个常规属性,例如

      struct InputField: View {
      
          var inputText: Binding<String>
          var title: String
          var placeholder: String
          var hasError = false       // << here !!
      
      // ...
      }
      

      现在只需调用即可

      InputField(inputText: $loginViewModel.username, title: "Username:", placeholder: "  Enter your username", 
           hasError: loginViewModel.checkUsernameisValid())   // << here !!
      

      使用 Xcode 12.1 / iOS 14.1 测试

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-29
        • 2013-09-25
        • 2018-04-09
        • 1970-01-01
        相关资源
        最近更新 更多