我是RxSwift的新手,并希望实现以下目标。我有一个email and password TextField。在两个textfields中输入文本后,应启用一个按钮。

在我的ViewController中,执行以下操作:

txtEmail.rx.text.asObservable()
  .bindTo(viewModel.email)
  .addDisposableTo(disposeBag)

txtPassword.rx.text.asObservable()
  .bindTo(viewModel.password)
  .addDisposableTo(disposeBag)

viewModel.buttonEnabled
  .bindTo(btnLogin.rx.isEnabled)
  .addDisposableTo(disposeBag)

这是我的ViewModel:
import Foundation
import RxSwift
import RxCocoa

class LoginViewModel {

    let email = Variable<String?>("")
    let password = Variable<String?>("")

    var buttonEnabled: Observable<Bool>

    init() {

        var processedEmail: Observable<String>!
        var processedPassword: Observable<String>!

        processedEmail = email.asObservable().map(String.toLower as! (String?) -> String).map(String.trimWhiteSpace as! (String?) -> String)
        processedPassword = password.asObservable().map(String.toLower as! (String?) -> String).map(String.trimWhiteSpace as! (String?) -> String)

        let emailValid = processedEmail.asObservable().map(String.isNotEmpty)
        let passwordValid = processedPassword.asObservable().map(String.isNotEmpty)

        buttonEnabled = Observable.combineLatest(emailValid, passwordValid) {
            return $0 && $1
        }

    }

    func didTapLoginButton() {
        print("hello \(email.value)")
    }
}

由于某种原因,我的initviewmodel方法永远不会完成。
有人能帮我吗?

最佳答案

似乎processedEmailprocessedPassword的定义正在生成崩溃,从而导致视图模型初始化无法完成。

更具体地说,String.toLowerString.trimWhiteSpace方法可能具有(String) -> String类型,但是在这里它们被强制转换为(String?) -> String

processedEmail = email.asObservable()
  .map { $0 ?? "" }
  .map(String.toLower)
  .map(String.trimWhiteSpace)

processedPassword = password.asObservable()
  .map { $0 ?? "" }
  .map(String.toLower)
  .map(String.trimWhiteSpace)

我只添加了.map { $0 ?? "" }。由于原始的Observable具有Observable<String?>类型,因此地图调用会将其转换为Observable<String>,然后可由String.toLowerString.trimWhiteSpace处理

09-30 14:25
查看更多