前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【iOS】RxSwift官方Example1,2--加法,检验篇

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

作者头像
MapleYe
发布2020-03-30 17:01:36
1.2K0
发布2020-03-30 17:01:36
举报
文章被收录于专栏:MapleYeMapleYe

前言

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

加法篇

功能说明

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

代码解释

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

源码如下:

代码语言:javascript
复制
@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

看下官方注释:

代码语言:javascript
复制
/// 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

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

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

代码语言:javascript
复制
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的长度是否大于指定的长度

代码语言:javascript
复制
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调用的次数。

官方注释:

代码语言:javascript
复制
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、监听按钮是否可点击

代码语言:javascript
复制
let everyThingValid = Observable.combineLatest(usernameValid, pwdValid) { (bool1, bool2) -> Bool in
            return bool1 && bool2
        }.shareReplay(1)

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

3、将监听的结果绑定UI

代码语言:javascript
复制
// 绑定
        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函数,看一下官方注释:

代码语言:javascript
复制
/**
    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、监听按钮的点击

代码语言:javascript
复制
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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 加法篇
    • 功能说明
      • 代码解释
        • 小结
        • 检验篇
          • 功能说明
            • 代码解释
              • 1、监听textFiled的长度是否大于指定的长度
              • 2、监听按钮是否可点击
              • 3、将监听的结果绑定UI
              • 4、监听按钮的点击
            • 小结
            • Demo地址
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档