【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<Void> {
return controlEvent(.touchUpInside)
}
}

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

小结

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

Demo地址

https://github.com/maple1994/RxSwfitTest

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容