【iOS】RxSwift官方Example1,2--加法,检验篇

前言

从今天起,我把自己学习RxSwift的官方Example时的感想写下来,或许对有疑惑的人有帮助吧。传送门

加法篇

功能说明

在这三个文本框任意输入数字后,将计算累加后的结果

代码解释

可以说,这个Demo是整个官方Example中最简单的。只需要对三个TextField的rx.text进行监听即可。

源码如下:

@IBOutlet weak var resultLabel: UILabel!
    @IBOutlet weak var textField3: UITextField!
    @IBOutlet weak var textField2: UITextField!
    @IBOutlet weak var textField1: UITextField!
    let disposeBag = DisposeBag()
    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "加法"

        // 监听三个textField的text变化,然后进行累+
        Observable.combineLatest(textField1.rx.text.orEmpty, textField2.rx.text.orEmpty, textField3.rx.text.orEmpty) { (value1, value2, value3) -> Int in
            return (Int(value1) ?? 0) + (Int(value2) ?? 0) + (Int(value3) ?? 0)
            }.map({$0.description}) // 将Int -> String
            .bind(to: resultLabel.rx.text) // 绑定结果
        .disposed(by: disposeBag)
    }

这里解释几点:

  • textField1.rx.text.orEmpty

看下官方注释:

/// Transforms control property of type `String?` into control property of type `String`.
    public var orEmpty: RxCocoa.ControlProperty<String> { get }

其实就是将String?转为String处理,这样我们就不需要考虑String?的情况,也就不需要考虑String为nil的情况。在Rxswift中,对于所有字符串的监听都是转为orEmpty处理的

  • combineLatest

其实将可观察序列中,将最新的序列组合起来处理。如下图所示:

再结合代码看,该函数的功能,就一目了然了。

Observable.combineLatest(textField1.rx.text.orEmpty, textField2.rx.text.orEmpty, textField3.rx.text.orEmpty) { (value1, value2, value3) -> Int in
            return (Int(value1) ?? 0) + (Int(value2) ?? 0) + (Int(value3) ?? 0)
            }.map({$0.description}) // 将Int -> String
            .bind(to: resultLabel.rx.text) // 绑定结果
        .disposed(by: disposeBag)

小结

总的来说,这个例子是非常的简单的。只是由于刚上手,xcode提示的抽风,可能会造成些困扰。

检验篇

这里写图片描述

功能说明

  • 监听username的长度是否大于5,否则pwd不可编辑
  • 监听pwd的长度是否大于5
  • 监听Do something的点击
  • username和pwd的text长度没有大于5时,不可点击do something按钮

代码解释

总体来说,该Example的难度也不大,所以简单的说明下吧。

1、监听textFiled的长度是否大于指定的长度

let usernameValid = usernameTextField.rx.text.orEmpty
        .map { (text) -> Bool in
            text.characters.count > minimalUsernameLength
        }.shareReplay(1)
        let pwdValid = pwdTextField.rx.text.orEmpty
            .map({ $0.characters.count > minimalPasswordLength })
        .shareReplay(1)

这里的shareReplay可以使自己的订阅“重播”,但是每次是记得自己【订阅】的最后几次(取决于你传入的num)内容,从而减少map调用的次数。

官方注释:

Returns an observable sequence that shares a single subscription to the underlying sequence, and immediately upon subscription replays maximum number of elements in buffer.

2、监听按钮是否可点击

let everyThingValid = Observable.combineLatest(usernameValid, pwdValid) { (bool1, bool2) -> Bool in
            return bool1 && bool2
        }.shareReplay(1)

跟上篇的加法一样,使用到了combineLatest函数,将username和pwd的Bool监听结果,从而判断按钮是否可点击。

3、将监听的结果绑定UI

// 绑定
        usernameValid.bind(to: pwdTextField.rx.isEnabled)
        .addDisposableTo(disposeBag)
        usernameValid.bind(to: usernameTipsLabel.rx.isHidden)
        .addDisposableTo(disposeBag)
        pwdValid.bind(to: pwdTipsLabel.rx.isHidden)
        .addDisposableTo(disposeBag)
        everyThingValid.bind(to: confirmButton.rx.isEnabled)
        .addDisposableTo(disposeBag)

这里使用到时的bind函数,看一下官方注释:

/**
    Creates new subscription and sends elements to observer.

    In this form it's equivalent to `subscribe` method, but it communicates intent better, and enables
    writing more consistent binding code.

    - parameter to: Observer that receives events.
    - returns: Disposable object that can be used to unsubscribe the observer.
    */
    public func bind<O>(to observer: O) -> Disposable where O : ObserverType, O.E == Self.E

大概意思就说,将一个被观察者与一个指定的观察者进行绑定,被观察者事件流中发出的所有事件元素都会让观察者接收。

在MVVM中,该方法主要用于View和ViewModel之间的绑定。

4、监听按钮的点击

confirmButton.rx.tap
            .subscribe(onNext: { [weak self] in
                self?.showAlert()
            })
        .addDisposableTo(disposeBag)

看下官方定义

extension Reactive where Base: UIButton {
/// Reactive wrapper for TouchUpInside control event.
public var tap: ControlEvent {
return controlEvent(.touchUpInside)
}
}

其实就是对touchUpInside的包装,那么按照以上的包装声明,我们也可以自己包装button的touchDown,touchUp等事件

小结

总的来说,这篇Example比起上一篇,稍微复杂了一点。其实不难看出,官方的Example在逐步的提高难度,并且慢慢地开始告诉你如何定制自己需要的Rx库。因此,我还是建议大家能够对官方Demo都过一篇,到时用的什么,都有个印象

Demo地址

https://github.com/maple1994/RxSwfitTest

猜你喜欢

转载自blog.csdn.net/bloody_leaves/article/details/77735241