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 流並將其寫入。