RxSwift小Demo

795 阅读1分钟

说明

此demo参照部分官方demo,仅供学习.

demo

  • 在Main.storyboard中搭建简单界面:

  • 在ViewController.swift中关联控件:

  • 新建loginService.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)
    }