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

xiaoxiao2021-02-28  152

前言

从今天起,我把自己学习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

转载请注明原文地址: https://www.6miu.com/read-20564.html

最新回复(0)