RxSwift和您可以使用响应式编程完成的出色工作-第一部分

我第一次听说反应式编程,这就是我的样子:

第二,第三和第四次也没有太大不同。 而且,即使我是第一次从事一个具有一些响应式代码的项目,也不要让我开始……那个表情在我脸上呆了整整两周!

现在我知道,很多人第一次遇到反应式编程时,都会有与我相同的感觉。 我也认识很多人,在经历了最初的不良印象之后,他们再也没有去研究它了,因为这听起来像是付出了太多的努力才开始使用。 但是我可以告诉你的事实是,我不认识一个人,在最终了解了它的工作原理之后,他才后悔参加了反应式编程。

现在我知道在线上有足够的资源来处理反应式和RxSwift的理论和复杂性,还有很多关于如何使用Rx进行各种操作的教程(我在其中最后放了一些链接)的帖子)。 不,我不会再编写有关流和可观察对象如何工作的教程或解释。 我想做的是提供一个简单,清晰,几乎没有理论的摘要,概述您可以使用RxSwift进行的操作以及为什么要使用它。 由于Rx有很多内容,我将在3个博客文章系列中对此进行细分。 让我们开始第一部分!

第1部分:数据绑定,控制事件和手势识别器

  1. 数据绑定

“数据绑定”听起来像是花哨的单词中的另一个,使事情听起来很漂亮,但这确实非常简单。 假设您有一个需要用户在文本字段中输入其名称的应用。 当他们这样做时,您要向他们打招呼,说“你好,\(名称)”。 很基本吧? 在非反应式应用程序中,应将UITextFieldDelegate协议添加到视图控制器,并实现textFieldDidEndEditing方法以跟踪用户何时完成其名称的书写,这时应设置标签的文本以对该名称问好。

不幸的是,与代表打交道可能会很烦人。 如果您有多个文本字段怎么办? 您将必须添加检查以确保用户已完成编辑正确的文本字段。 而且,如果客户决定在用户​​输入姓名时(而不只是在完成文本字段编辑时)更新标签,该怎么办?

在反应式中,这种行为可以通过数据绑定来实现。 简而言之,您想将用户在文本字段中提供给您的数据绑定到另一个UI对象(标签)。 使用RxSwift,没有比绑定数据更简单的了。 在我刚才提到的情况下,这将是这样的:

  var nameField = UITextField() 
var helloLabel = UILabel()
 覆盖func viewDidLoad(){ 
nameField.rx.text.map {“ Hello \($ 0)”}
.bindTo(helloLabel.rx.text)
}

让我们分解一下:首先,我们获取文本字段的文本,然后将其映射为要在标签中设置的格式。 在这种情况下,它只是意味着在文本(又称用户名)之前添加一个问候,由于map是一个闭包,因此可以简单地称为无名闭包参数( $0是第一个参数, $1是第二个参数,依此类推)。 然后,我们将该映射文本绑定到标签中的文本。 就是这样,工作完成了! 没有委托,没有if语句,只有一点简单明了的代码。

现在,我知道您在想什么:这很重要,但实际上有多少应用程序会执行此类操作? 我只能告诉您的是,不要卡在示例中。 能够将数据绑定到视图非常强大,只需考虑一下:您可以根据天气改变视图的backgroundColor,根据一些数据,使用一些非常简单的逻辑,根据用户的位置在商店应用中导航用户可能会改变。 再说一次,我不会对理论进行过多介绍,但这是背后的主要思想。

2.控制事件和手势识别器

如果您不熟悉事件,那么它们基本上就是用户可以在您的应用程序上执行的任何操作:轻击,滑动,拖动等等。 当用户按下按钮时,您的应用会将其检测为类型为.touchUpInside的UIControlEvent。 如果使用情节提要,则在创建@IBActions时可能已经看到了。 在这种情况下,您可能没有对按钮操作考虑太多。 我已经写了很多关于为什么我从不使用情节提要的文章,如果您像我一样,那么这段代码应该看起来非常熟悉:

  var button = UIButton() 
 覆盖func viewDidLoad(){ 
button.addTarget(#selector(ViewController.loginUser),目标:自我,事件:.touchUpInside
}
  func loginUser(){ 
//在这里实现
}

我要直截了当地说:我讨厌选择器。 它们不清楚,导致脏的代码分散,并且增加了出错的风险。 使用Rx,这是将操作添加到按钮的方式:

  var button = UIButton() 
var disposeBag = DisposeBag()
 覆盖func viewDidLoad(){ 
button.rx.tap.subscribe {onNext _ in
//在这里实现
} .addDisposableTo(disposeBag)
}

不要在这里过于迷恋disposeBag或subscribe调用,只需将它们视为使代码正常工作的必要步骤(您将在本文结尾处引用的资源中找到有关这些信息的更多信息) 。

当点击没有任何控件事件的视图(例如UILabel或UIImage)时,如果需要执行某种逻辑怎么办? 不幸的是,使用UIKit的唯一方法是使用我最不喜欢的UIKit另一个功能:手势识别器。

 让标签= UILabel() 
 覆盖func viewDidLoad(){ 
//显示手势识别器的示例
 让gestureRecognizer = UITapGestureRecognizer(目标:自我,行动​​:“ handleTap:”) 
label.addGestureRecognizer(gestureRecognizer)
}
  func handleTap(){ 
//您的逻辑在这里
}

您需要响应的任何手势(例如,滑动,拖动,平移等)都一样。如果您希望视图响应多个手势识别器,则需要创建并添加每个手势识别器及其适当的操作方法。 这不仅涉及到很多样板代码,而且令人难以置信的混乱和容易出错。

您已经猜到了,Rx使这一过程变得异常简单:

 让标签= UILabel() 
让disposeBag = DisposeBag()
 覆盖func viewDidLoad(){ 
label.rx.gesture(.tap).subscribe {onNext(gesture)in
//您的逻辑在这里
} .addDisposableTo(disposeBag)
}

如果您需要处理多个手势,这就是您要做的一切:

 让标签= UILabel() 
让disposeBag = DisposeBag()
 覆盖func viewDidLoad(){ 
label.rx.gesture(.tap,.pan,.swipeUp).subscribe {onNext(gesture)in
切换手势{
case .tap://做点什么
case .pan://做点什么
case .swipeUp://做点什么
默认值:break
}
} .addDisposableTo(disposeBag)
}

所有这些都由称为RxGesture的RxSwift视图手势包装提供。

今天我将在这里结束,但是请继续关注本系列的下一部分! 不要犹豫,在评论中提出您的问题,并让我知道您是否希望我讲些什么,或者我可以改进的!

资源

ReactiveX / RxSwift
RxSwift – Swift的响应式编程 github.com Swift带来的功能性反应真棒
功能还是反应式编程? 为什么不同时? Ash Furrow在本次演讲开始时简要介绍了功能… realm.io 反应性迅捷
我在Swift中进行响应式编程的旅程-以及随之而来的iOS应用程序。 medium.com DTVD / RxSwift简介您错过了
RxSwift简介-您已经错过了– RxSwift的简介您已经错过了 github.com RxSwift示例1 –基础知识。 – iOS,Android和Ruby开发团队| 机器人上的机器人
Swift是一种无论您做什么都感觉很好的语言。 它连接了其他语言的各个方面…… www.thedroidsonroids.com 我创建iOS应用程序– RxSwift适合我吗?
从地图和过滤器跳转到需要调用一个 realm.io的呈现视图控制器或搜索栏非常困难。