說明
此demo參照部分官方demo,僅供學習.
複製程式碼
demo
- 在ViewController.swift中關聯控制元件:
enum ValidStatus {
case fail(msg: String)
case success(msg: String)
}
class loginService {
let nameValid : Observable<ValidStatus>
let pwdValid : Observable<ValidStatus>
let repwdValid : Observable<ValidStatus>
let canLogin : Observable<Bool>
init(_ observableString: (name: Observable<String>, pwd: Observable<String>, repwd: Observable<String>)) {
nameValid = observableString.name.map {
if ($0.count == 0) {
return ValidStatus.fail(msg: "請輸入name")
}else if ($0.count > 12) {
return ValidStatus.fail(msg: "name長度太長了")
}else {
return ValidStatus.success(msg: "輸入name合法")
}
}
pwdValid = observableString.pwd.map {
if ($0.count == 0) {
return ValidStatus.fail(msg: "請輸入pwd")
}else if ($0.count != 6) {
return ValidStatus.fail(msg: "pwd只支援6位")
}else {
return ValidStatus.success(msg: "輸入pwd合法")
}
}
repwdValid = Observable.combineLatest(observableString.pwd, observableString.repwd) {
pw, pw1 in
if (pw == pw1) {
return ValidStatus.success(msg: "輸入repwd合法")
}else {
return ValidStatus.fail(msg: "與pwd不一致,請重新輸入")
}
}
canLogin = Observable.combineLatest(nameValid, pwdValid, repwdValid) {
valid0, valid1, valid2 in
var valid = true
switch valid0 {
case .success:
valid = true
case .fail:
return false
}
switch valid1 {
case .success:
valid = true
case .fail:
return false
}
switch valid2 {
case .success:
valid = true
case .fail:
return false
}
return valid
}
}
}
複製程式碼
- 建立BindingExtensions.swift檔案,為Label新增新的可繫結屬性
struct ValidationColors {
static let successColor = UIColor(red: 138.0 / 255.0, green: 221.0 / 255.0, blue: 109.0 / 255.0, alpha: 1.0)
static let failColor = UIColor.red
}
extension ValidStatus {
var txtColor : UIColor {
switch self {
case .success:
return ValidationColors.successColor
default:
return ValidationColors.failColor
}
}
var description : String {
switch self {
case let .success(msg):
return msg
case let .fail(msg):
return msg
}
}
}
extension Reactive where Base: UILabel {
var validStatus : Binder<ValidStatus> {
return Binder(base) { label, result in
label.textColor = result.txtColor
label.text = result.description
}
}
}
複製程式碼
- 最後在viewController.swift中編寫繫結程式碼:
let bag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
indicatorView.isHidden = true
let service = JLLoginInOneService((usernameField.rx.text.orEmpty.asObservable(),pwdField.rx.text.orEmpty.asObservable(),rePwdField.rx.text.orEmpty.asObservable()))
service.nameValid.bind(to: usernameValidLabel.rx.validStatus).disposed(by: bag)
service.pwdValid.bind(to: pwdValidLabel.rx.validStatus).disposed(by: bag)
service.repwdValid.bind(to: rePwdValidLabel.rx.validStatus).disposed(by: bag)
service.canLogin.bind(to: loginBtn.rx.isEnabled).disposed(by: bag)
loginBtn.rx.tap.subscribe { _ in
print("tap")
self.indicatorView.isHidden = false
self.indicatorView.startAnimating()
}.disposed(by: bag)
}
複製程式碼