美文网首页iOS-swiftswift收藏问题
一头扎进 RxSwift(一)

一头扎进 RxSwift(一)

作者: 張無忌 | 来源:发表于2017-04-23 11:38 被阅读1581次

概述

从 C 语言的面向过程开始,到后来的 Objective-C、C++ 面向对象编程,风靡了编程界几十年。后来 Java 的 Spring 框架提出了面向切面编程的思想,但是并未在 iOS 开发中流行起来。如今,码友们听得最多的应该是函数响应式编程。本文算是笔者的一个学习记录过程。

RxSwift 简介

RxSwift 是 GitHub 的 ReactiveX 团队出的一套框架,针对 Swift 语言。除此之外,ReactiveX 还推出了 RxJava,RxAndroid,RxPHP 等蕴含类似思想的框架。

RxSwift 安装

如果你还没有掌握 CocoaPods,请先学习,依赖管理是学习每一种语言都需要掌握的技能。建议通过 Pods 来安装 RxSwift,在Podfile文件中引入 RxSwift 和 RxCocoa。

pod 'RxSwift'
pod 'RxCocoa'

RxSwift 是 Swift 语言的函数响应式编程框架。
RxCocoa 则是对苹果原声面向对象 Api 的封装。

在需要用到 RxSwift 相关内容的类里面,引入模块即可。

import RxSwift
import RxCocoa

RxSwift 简单应用(一)

需求:现在界面上有两个 UIButton,我想监听它们的点击事件。

传统做法

按照以往的做法,我们会首先增加按钮的点击监听,然后自定义一个方法,最后再方法内部去处理点击之后的逻辑。

// 增加点击监听
button1.addTarget(self, action: #selector(clickButton1), for: .touchUpInside)
button1.addTarget(self, action: #selector(clickButton2), for: .touchUpInside)
// 实现点击之后的逻辑
@objc func clickButton1() {
    print("按钮1 被点")
}
@objc func clickButton2() {
    print("按钮1 被点")
}

这样做可能面临的问题是:代码分离度比较高、后期代码维护费力等等。

RxSwift 做法

下面来看一看用 RxSwift 来实现上述需求。

button1.rx.tap.subscribe { (event: Event<()>) in
    print("按钮1 被点")
}

当你写下button1.rx.tap后,试图通过“.”语法把后面的语句敲出来时,会发现没有提示。


我的解决方法是重新实例化一个 UIButton,然后就可以看到代码提示,写完代码之后再替换。

不知道哪位码友有更好的解决方案?

subscribe是订阅的意思,整体可以理解为订阅button1的点击事件,当按钮被点击是,通过闭包回调。这样就实现了监听按钮点击并处理点击事件的需求。但是当前代码会报一个警告:

警告:返回值没有被使用
解决:
// 类里面懒加载 DisposeBag 对象
fileprivate lazy var bag = DisposeBag()

// 增加点击监听
button1.rx.tap.subscribe { (event: Event<()>) in
    print("按钮1 被点")
}.addDisposableTo(bag)

.addDisposableTo(bag) 的作用可以先不用理会,后面会提到,现在就当它是用来消除警告的语句。

RxSwift 简单应用(二)

需求:界面上有2个 UITextField,我想监听它们的输入。

传统做法

成为文本框的代理

textField1.delegate = self
textField2.delegate = self

实现文本框协议

// MARK: - UITextFieldDelegate
extension ViewController: UITextFieldDelegate {
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        // 判断是哪一个输入框发生改变
        if textField == textField1 {
            print("输入框1 改变")
        } else {
            print("输入框2 改变")
        }
        
        return true
    }
}

这样做可能面临的问题:界面有多个文本框,需要每个都实现代理,并且需要判断是哪一个文本框发生了改变,维护成本比较高,代码可读性差。

RxSwift 做法

先订阅 UITextField,文字输入改变时通过闭包回调。

textField1.rx.text.subscribe { (event: Event<String?>) in
    print(event.element)
}.addDisposableTo(bag)

打印出来的结果有点吓唬人,再一看element的类型也就不足为奇了。

还有另外一种写法:
textField1.rx.text.subscribe(onNext: { (str: String?) in
    print(str)
}).addDisposableTo(bag)

这样打印出来的东西友好了许多。

RxSwift 简单应用(三)

需求:现在我们在上面例子的基础上,增加两个 UILabel,实时显示文本框所输入的内容。

RxSwift 做法

textField1.rx.text
    .bind(to: label1.rx.text)
    .addDisposableTo(bag)

把文本输入框的值,绑定到 UILabel 上面。

RxSwift 简单应用(四)

在平时的开发中,我们经常使用KVO来监听某个对象的某一属性改变。KVO 使用流程和监听按钮点击差不多,首先需要添加监听,然后覆盖系统方法进行逻辑处理。

传统做法

// 对 frame 属性添加监听
label1.addObserver(self, forKeyPath: "frame", options: .new, context: nil)
// 覆盖父类方法,实现监听回调
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if label1.isEqual(object) {
        if keyPath == "frame" {
            print("位置发生改变")
        }
    }
}

RxSwift 做法

label1.rx.observe(CGRect.self, "frame")
    .subscribe(onNext: { (frame: CGRect?) in
        print(frame)
    })
    .addDisposableTo(bag)

observe 方法接收 2 个参数:

  1. 监听的属性的类型
  2. 监听的属性的名字

监听完毕之后,对该事件进行订阅,通过闭包形式进行回调。

除此之外,还可以直接监听属性的改变,例如:监听 UIScrollView 的偏移量。


读到这里,算对函数响应式编程RxSwiftRxCocoa有了初步的了解和认识。

如果对你有所帮助,请点一个👍 ,谢谢!

相关文章

  • 一头扎进 RxSwift(一)

    概述 从 C 语言的面向过程开始,到后来的 Objective-C、C++ 面向对象编程,风靡了编程界几十年。后来...

  • 一头扎进大海

    扑通一声 我扎进了大海 没想到 冬天 海水是温暖的 我自由地 蛙着 仰着 天空飞过喷着白烟的航班 巨轮正在驶...

  • 一头扎进去

    工作一如既往的忙,才发现自己一头扎进去的时候,一路还会有多少颠簸,整个人忙起来的时候就好了。 除了要不断磨练自己的...

  • 一头扎进黑夜里

    头一次加班到将近零点 工作单位在山里 走出办公室 夜色中有雾气 晚风微凉 骑电驴回家 午夜的城市 睡着了大半 道路...

  • 一头扎进CBD商圈

    好久没写点什么感慨下人生了,据九月摩羯座运势秘指:本月有跳槽想法,抓住此机会,人生会有大的转折。 原公...

  • 一头扎进自由里

    记得两年前,有一天突然有一种无论做什么都踩在点儿上的感觉,就像是无论做什么都是刚好做的都是合适的事情,都是当时当下...

  • 无标题文章

    你又一头扎进了玩具堆,就像我一头扎进淘宝一样 回不了头 什么都想买,哈哈

  • 一头扎进纯美小时光

    1.商品名称: 中文:Warehouse2017春夏纯棉单肩褶皱荷叶边上衣 英文:COTTON RUFFLE ON...

  • 一头扎进新生活

    我从前认为久别总会重逢,热爱不会停息。总以为自己永远年少,十年饮冰,难凉热血,可是越往前走才发现,一路前行一路失去...

  • 一头扎进了文案狗

    人生很戏剧化,上一刻让你开心的找不着北,下一刻,很可能就会把你打入地狱。所以在你站得高的时候,千万不要得意,不然摔...

网友评论

  • 小明2021:点语法没提示可以敲空格然后方法的首字母就OK了
  • 混不吝丶:有没有2
    天净沙:@任兴金 同问有没有 qq 群
    任兴金:你好,我也正在学RxSwift 有没有qq可以交流一下
  • 风与心愿:代码补全那个bug,我的解决办法是:
    let temp = textField.rx.text
    temp.subscribe(...) //使用一个临时变量,然后就能使用点语法了,等写完了再把 temp 干掉即可
  • efcb9d5bedaf:请教,跨界面传值怎么实现啊?
    TeacherXue:闭包呀
    efcb9d5bedaf:@張無忌 就是不会传值:sweat:
    張無忌:@水电管家v 兄弟,我也是初学,还在学习中

本文标题:一头扎进 RxSwift(一)

本文链接:https://www.haomeiwen.com/subject/epiezttx.html