首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >译文-MVVM系列-RxSwift简介及Reactive Programming可以做的事情

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

作者头像
iOS Development
发布2019-02-14 17:42:14
1.5K0
发布2019-02-14 17:42:14
举报

本文翻译自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(闭包),所以可以用无名闭包参数(

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

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Part 1: Data Binding, control events and gesture recognizers
    • 1. Data Binding
      • 2. Control Events and Gesture Recognizers
      • Resources
      相关产品与服务
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档