RxSwift小Demo

砳砳發表於2018-03-22

說明

此demo參照部分官方demo,僅供學習.
複製程式碼

demo

  • 在Main.storyboard中搭建簡單介面:

RxSwift小Demo

  • 在ViewController.swift中關聯控制元件:

RxSwift小Demo

  • 新建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)
    }
複製程式碼

相關文章