【发布时间】:2017-04-24 16:53:04
【问题描述】:
我正在使用 MVVM 模式,并尝试仅在用户按下登录按钮时显示警告标签。现在它们没有出现,因为我不知道如何仅在用户操作时显示它们。然后在用户开始编辑时,相应标签的警告应该隐藏。 这是我的 ViewController 处理对 viewModel 的引用:
import UIKit
import RxSwift
import RxCocoa
class RxLoginViewController: UIViewController {
@IBOutlet weak var signInButton: UIButton!
@IBOutlet weak var phoneNumberTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
@IBOutlet weak var phoneWarningLabel: UILabel!
@IBOutlet weak var passwordWarningLabel: UILabel!
fileprivate var viewModel: RxLoginViewModel?
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
viewModel = RxLoginViewModel(phoneNumber: phoneNumberTextField.rx.text.orEmpty.asDriver(), passwordText: passwordTextField.rx.text.orEmpty.asDriver())
addBindsToViewModel(viewModel: viewModel!)
setupButtons()
}
fileprivate func addBindsToViewModel(viewModel: RxLoginViewModel) {
phoneNumberTextField.rx.text
.orEmpty
.asObservable()
.debug("phoneNumberTextField")
.bindTo(viewModel.phoneNumberText)
.addDisposableTo(disposeBag)
passwordTextField.rx.text
.orEmpty
.asObservable()
.debug("passwordTextField")
.bindTo(viewModel.passwordText)
.addDisposableTo(disposeBag)
viewModel.showPhoneWarning
.asDriver()
.debug("showPhoneWarning")
.drive(onNext: { [weak self] showWarning in
UIView.animate(withDuration: 0.2) {
self?.phoneWarningLabel.isHidden = !showWarning
}}
)
.addDisposableTo(disposeBag)
viewModel.showPasswordWarning
.asDriver()
.debug("showPasswordWarning")
.drive(onNext: { [weak self] showWarning in
UIView.animate(withDuration: 0.2) {
self?.passwordWarningLabel.isHidden = !showWarning
}
})
.addDisposableTo(disposeBag)
viewModel.credentialsValid
.debug("credentialsValid")
.drive(onNext: { [weak self] valid in
self?.signInButton.isEnabled = valid
self?.signInButton.alpha = valid ? 1 : 0.5
})
.addDisposableTo(disposeBag)
}
private func setupButtons() {
signInButton.rx.tap
.bindTo(viewModel!.signInAction)
.addDisposableTo(disposeBag)
}
}
和 ViewModel:
class RxLoginViewModel {
let dataManager = DataManager.sharedInstance()
private let disposeBag = DisposeBag()
//MARK: - Model proprties
var phoneNumberText = Variable<String>("")
var passwordText = Variable<String>("")
var signInAction: Variable<Void> = Variable<Void>()
var showPhoneWarning = Variable(false)
var showPasswordWarning = Variable(false)
var credentialsValid: Driver<Bool>
var canLogIn = Variable(false)
init(phoneNumber: Driver<String>, passwordText: Driver<String>) {
let phoneValid = phoneNumber
.distinctUntilChanged()
.throttle(0.3)
.map { ($0 =~ RegEx.phone) }
let passwordValid = passwordText
.distinctUntilChanged()
.throttle(0.3)
.map { ($0.utf8.count > 5) }
credentialsValid = Driver.combineLatest(phoneValid, passwordValid) { $0 && $1 }
phoneNumber.debug("phone number driver")
.drive(onNext: {_ in self.showPhoneWarning.value = false })
.addDisposableTo(disposeBag)
phoneNumber.debug("password driver")
.drive(onNext: {_ in self.showPasswordWarning.value = false })
.addDisposableTo(disposeBag)
credentialsValid.asObservable()
.bindTo(canLogIn)
.addDisposableTo(disposeBag)
// actions handler
signInAction
.asObservable()
.debug("signInAction")
.do(onNext: { _ in
// show warning for any invalid textfield
// filter both valid fields
} )
// sent url request
.subscribe(onNext: { status in
self.dataManager.login(withPhone: self.phoneNumberText.value, email: "", password: self.passwordText.value, success: { ( result ) in
if let response = result as? [String : Any], response["aboutMe"] == nil {
self.dataManager.currentUser().userId = response["id"] as? NSNumber
// self.dataManager.update(.fillProfile)
}
}, failure: { (error) in
// print(error.localizedDescription)
})
})
.addDisposableTo(disposeBag)
}
我应该怎么做才能显示任何无效文本字段的警告以及如何过滤我的 ViewModel 中的两个有效字段?
【问题讨论】:
标签: ios swift mvvm reactive-cocoa rx-swift