2016-12-05 40 views
0

我是RxSwift的新用户,想要实现以下功能。我有一个email and password TextField。当您在textfields中输入文本时,应该启用一个按钮。使用RxSwift逻辑启用按钮

在我的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)") 
    } 
} 

出于某种原因,我viewmodel永远不会结束的init方法。 有人可以帮我吗?

+0

你是什么意思“永远不会完成”? – tomahh

+0

@tomahh我在init方法上得到一个EXC_BAD_INSTRUCTION – Steaphann

+0

你确定'toLower'和'trimWhiteSpace'实际上有'(String?) - > String'类型吗?这是我怀疑可能导致事故的唯一线路。 – tomahh

回答

1

看起来像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<String?>地图通话将它转换为Observable<String>然后将由String.toLowerString.trimWhiteSpace

+0

这对我有用!谢谢 ! – Steaphann

0

我试过的初始化这个例子是加工和它似乎工作:

init() { 
    let processedEmail = email.asObservable() 
     .map { $0 ?? "" } 
     .map { $0.lowercased() } 
     .map { !$0.isEmpty } 

    let processedPassword = password.asObservable() 
     .map { $0 ?? "" } 
     .map { $0.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) } 
     .map { !$0.isEmpty } 

    buttonEnabled = Observable.combineLatest(processedEmail, processedPassword) { 
     return $0 && $1 
    } 
}