译文-MVVM系列-RxSwift简介及Reactive Programming可以做的事情

作者 : 开心源码 本文共3596个字,预计阅读时间需要9分钟 发布时间: 2022-05-12 共135人阅读

本文翻译自RxSwift and the awesome things you can do with Reactive Programming?—?Part I(需要科学上网)

注:reactive programming,译者觉得是一个「专有名词」,同时也为了让读者更好了解其中含义,所以不翻译为「响应式编程」,直接用英语原文。

正文:

第一次接触reactive programming,我的表情是这样的:

First Impressions of reactive programming

第二、第三、第四次接触,也是心累。第一次参加到有reactive code的项目,简直是老鼠拉龟——无从下手。

我现在知道很多人第一次接触reactive programming也是和我一样的心情。而且很多人对reactive programming留下坏印象之后,再也不想去碰了,用起来太吃力儿。不过,另外一个事实是,在我所认识的人中,当他们切底弄明白reactive programming后,没有一个人后悔去用它。

网上已经有很多文章详情reactive和RxSwift,也有很多教程教大家怎样解决Rx中的各种状况(文本后面会放少量相关链接)。所以这里不打算再写一篇教程去解释streams和observables的原理。我想提供一个简单、清晰、不涉及理论知识的总结,详情用RxSwift可以做什么,以及为什么要用RxSwift。由于Rx涉及很多内容,所以打算用一个系列3篇文章来详情。下面开始第一部分!

Part 1: Data Binding, control events and gesture recognizers

数据绑定,控制事件和手势识别

1. Data Binding

「Data binding/数据绑定」,这名词听起来有点故弄玄虚,不过其实很简单。如果你有一个app,需要客户在text field中输入他们的名字。用「”Hello, \(Name)”」来做问候。很简单的需求,对吧。在non-reactive app中,你需要在view controlelr中增加UITextFieldDelegate协议,并实现textFiledDidEndEding方法监测客户什么时候输入完他们的名字,而后增加一个label来显示输入的内容。

悲催的地方在于,用delegates来解决这个需求,相当繁琐。如果有多个text field呢?还需要增加判断,检查正在编辑的是哪个text field。假如用户要求label要和text field的输入保持同步升级呢?

在reactive中,此类需求可以用data binding来实现。简单来说,你需要绑定text field的数据到另一个UI对象(label)。利用RxSwift,没有比data binding更简单的了。在这个需求中,大概写成这个样子:

var nameField = UITextField()var helloLabel = UILabel()override func viewDidLoad() {    nameField.rx.text.map { "Hello \($0)" }                     .bindTo(helloLabel.rx.text)}

让我们分析一下代码:首先,我们拿到text field的文本,而后映射(map)成我们需要赋值给label的内容。这里只是简单地在输入内容前加一个「Hello」,由于map是一个closure(闭包),所以可以用无名闭包参数(0是第一个参数,1是第二个参数,依此类推)。而后我们将映射出来的文本绑定到label的text属性。这样就OK了。不用delegates、不用if,只要要几行简明扼要的代码。

可能你会觉得:看起来很美好,但是有多少app会有这样的需求?这里只能告诉你,不要囿于这个例子。能够将数据绑定到视图(views)是非常强大的功能,想想看:你可以根据天气的变化来改变视图的背景颜色,根据客户的位置导航到对应的商店的app……再次强调,本文不会太深入理论,不过这(数据绑定)就是其中的精髓。

2. Control Events and Gesture Recognizers

事件(events),假如你对这个概念不熟习,基本上可以了解为:客户可以在app上执行的所有操作:tap, swipe, drag等等。当客户点击一个按钮,app会检测到这是UIControlEvent中的.touchUpInside。假如你用的是storyboards,在创立@IBAction的时候就会看到.touchUpInside。在这个例子中,不需要考虑按钮的点击事件。我曾经写过关于为什么我素来不用storyboards,假如你和我一样(不用storyboard),下面代码看起来就会非常熟习:

var button = UIButton()override func viewDidLoad() {    button.addTarget(#selector(ViewController.loginUser), target: self, event: .touchUpInside}func loginUser() {    // Implementation here}

实不相瞒,我非常讨厌selectors,他们不够清晰,而且污染、分散了代码,还添加了出错的风险。而用Rx,则用如下方式增加按钮的action:

var button = UIButton()var disposeBag = DisposeBag()override func viewDidLoad() {    button.rx.tap.subscribe { onNext _ in        // Implementation here    }.addDisposableTo(disposeBag)}

别被disposeBag或者者subscribe唬住,把他们看作是必要、固定的步骤就好了(你可以在文末的链接中找到更多相关资料)。

当没有control event的控件(比方UILabel、UIImage)被点击时,你需要执行某段代码,怎样办?非常悲催,只能用我非常讨厌的方法:增加gesture recognizers(手势识别)。

let label = UILabel()override func viewDidLoad() {    // Show example of gesture recognizers    let gestureRecognizer = UITapGestureRecognizer(target: self, action: “handleTap:”)    label.addGestureRecognizer(gestureRecognizer)}func handleTap() {    // Your logic here}

响应其余如swipe、drag、pan等手势也相似。假如希望响应多个手势,就需要分别创立、增加,这样不仅会产生很多重复代码,代码还容易混乱、出错。

你已经猜到了,Rx可以轻而易举地应对:

let label = UILabel()let disposeBag = DisposeBag()override func viewDidLoad() {    label.rx.gesture(.tap).subscribe {onNext (gesture) in        // Your logic here    }.addDisposableTo(disposeBag)}

假如需要解决多个手势,只要要这样解决:

let label = UILabel()let disposeBag = DisposeBag()override func viewDidLoad() {    label.rx.gesture(.tap, .pan, .swipeUp).subscribe { onNext (gesture) in        switch gesture {        case .tap: // Do something        case .pan: // Do something        case .swipeUp: // Do something         default: break               }            }.addDisposableTo(disposeBag)}

这些在RxGesture中都有提供。

今天到此结束,但是请继续关注本系列其余文章。如有疑问或者建议,评论区,不吝赐教。

Resources

ReactiveX/RxSwift

Functional Reactive Awesomeness With Swift

Reactive Swift

The-introduction-to-RxSwift-you-have-been-missing

RxSwift by Examples 1 – The Basics

I create iOS apps – is RxSwift for me?

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1hsnfn0jgsjiu

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 译文-MVVM系列-RxSwift简介及Reactive Programming可以做的事情

发表回复