RxCocoa 和 ControlEvents

RxSwift 不仅提供了控制数据的方法,还提供了以被动方式表示用户操作的方法。

RxCocoa 包含你需要的一切。它将大多数 UI 组件的属性包装到 Observables 中,但不是真的。有一些升级的 Observables 称为 ControlEvents(代表事件)和 ControlProperties(代表属性,惊喜!)。这些东西在引擎盖下引起了流动,但也有一些细微差别:

  • 它永远不会失败,所以没有错误。
  • 它将取消分配控件上的序列。
  • 它在主线程(MainScheduler.instance)上传递事件。

基本上,你可以像往常一样使用它们:

button.rx_tap.subscribeNext { _ in   // control event
    print("User tapped the button!")
}.addDisposableTo(bag)

textField.rx_text.subscribeNext { text in // control property
    print("The textfield contains: \(text)")
}.addDisposableTo(bag)
// notice that ControlProperty generates .Next event on subscription
// In this case, the log will display 
// "The textfield contains: "
// at the very start of the app.

这一点非常重要:只要你使用 Rx,忘记了 @IBAction 的东西,你需要的所有东西都可以立即绑定和配置。例如,视图控制器的 viewDidLoad 方法是描述 UI 组件如何工作的良好候选者。

好的,另一个例子:假设我们有一个文本字段,一个按钮和一个标签。我们想要在点击按钮时验证文本字段中的文本,并在标签中显示结果。是的,似乎是另一个验证 - 电子邮件任务,是吗? **** ****

首先,我们抓住 button.rx_tap ControlEvent:

----()-----------------------()----->

这里空括号显示用户点击。接下来,我们将使用 withLatestFrom 运算符在 textField 中编写的内容(请在此处查看 ,假设上部流表示用户点击,底部表示文本字段中的文本)。

button.rx_tap.withLatestFrom(textField.rx_text)

----("")--------------------("123")--->
//  ^ tap   ^ i wrote 123    ^ tap

很好,我们有一串要验证的字符串流,只有在我们需要验证时才会发出。

任何 Observable 都有如 mapfilter 这样熟悉的操作符,我们将采用 map 来验证文本。自己创建 validateEmail 函数,使用你想要的任何正则表达式。

button.rx_tap                                // ControlEvent<Void>
        .withLatestFrom(textField.rx_text)   // Observable<String>
        .map(validateEmail)                  // Observable<Bool>
        .map { (isCorrect) in
            return isCorrect ? "Email is correct" : "Input the correct one, please"
        }                                    // Observable<String>
        .bindTo(label.rx_text)              
        .addDisposableTo(bag) 

完成! 如果你需要更多自定义逻辑(如出现错误时显示错误视图,成功转换到另一个屏幕……),只需订阅最终的 Bool 流并将其写入。