【发布时间】:2018-08-21 09:27:15
【问题描述】:
我正在学习 RxSwift,我已经尝试了使用它的基本登录 UI。我的实现如下。
LoginViewController:
fileprivate let loginViewModel = LoginViewModel()
fileprivate var textFieldArray: [UITextField]!
override func viewDidLoad() {
super.viewDidLoad()
textFieldArray = [textFieldUserName, textFieldPassword, textFieldConfirmPassword]
textFieldUserName.delegate = self
textFieldPassword.delegate = self
textFieldConfirmPassword.delegate = self
loginViewModel.areValidFields.subscribe(
onNext: { [weak self] validArray in
for i in 0..<validArray.count {
if validArray[i] {
self?.showValidUI(index: i)
} else {
self?.showInValidUI(index: i)
}
}
},
onCompleted: {
print("### COMPLETED ###")
},
onDisposed: {
print("### DISPOSED ###")
}).disposed(by: loginViewModel.bag)
}
func showValidUI(index: Int) {
textFieldArray[index].layer.borderColor = UIColor.clear.cgColor
}
func showInValidUI(index: Int) {
textFieldArray[index].layer.borderColor = UIColor.red.cgColor
textFieldArray[index].layer.borderWidth = 2.0
}
extension LoginViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let inputText = (textField.text! as NSString).replacingCharacters(in: range, with: string)
switch textField {
case textFieldUserName:
loginViewModel.updateUserName(text: inputText)
case textFieldPassword:
loginViewModel.updatePassword(text: inputText)
case textFieldConfirmPassword:
loginViewModel.updateConfirmedPassword(text: inputText)
default:
return false
}
return true
}
}
LoginViewModel:
class LoginViewModel {
private var username: String!
private var password: String!
private var confirmedPassword: String!
fileprivate let combinedSubject = PublishSubject<[Bool]>()
let bag = DisposeBag()
var areValidFields: Observable<[Bool]> {
return combinedSubject.asObservable()
}
init() {
self.username = ""
self.password = ""
self.confirmedPassword = ""
}
/*deinit {
combinedSubject.onCompleted()
}*/
func updateUserName(text: String) {
username = text
if username.count > 6 {
combinedSubject.onNext([true, true, true])
} else {
combinedSubject.onNext([false, true, true])
}
}
func updatePassword(text: String) {
password = text
if password.count > 6 {
combinedSubject.onNext([true, true, true])
} else {
combinedSubject.onNext([true, false, true])
}
}
func updateConfirmedPassword(text: String) {
confirmedPassword = text
if confirmedPassword == password {
combinedSubject.onNext([true, true, true])
} else {
combinedSubject.onNext([true, true, false])
}
}
}
使用此代码,当我移回导航堆栈时会打印已处理的消息。
但是,如果我继续前进,则不会打印已处理的消息。处置 observable 的正确方法是什么?
【问题讨论】: