UITextFieldとUILabelをRxSwiftでバインディングする方法

概要

タイトルで「バインディング」という言葉を使いました。 しかしRxSwift初心者にとってまたiOS開発者にとって一番勘違いを起こしてしまうのがこの「バインディング」だと思ってます。 バインディングと格好良く行っていますが要するにSwiftのクロージャーの中で処理を繋げることと同じだと思っています。

今回はそれをUITextFieldとUILabelとの接続を通して理解を深めたいと思います。

開発環境について

Xcode: 10.1
Swift: 4.2
RxSwift: 4.4.0
RxCocoa: 4.4.0

バインディング

前回はUITextFieldのRxSwiftで他の@IBOutletと連携させない単独の処理を説明しました。 今回はUILabelと連携する方法についてです。

storyboardの内容は以前と変わりません。

UITextFieldのRxSwift処理の書き方について

ViewControlleの編集を行います。

import UIKit
import RxCocoa
import RxSwift

class ViewController: UIViewController {
    
    @IBOutlet weak var button: UIButton!
    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var textField: UITextField!
    
    var disposeBag = DisposeBag()
    var count = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        textField.rx.text.orEmpty.asDriver()
            .drive(onNext: { [unowned self] text in
                // 入力するたびにこの処理が走る
                print("text: \(text)")
                print("isEditing: \(self.textField.isEditing)") // self.textField.isEditing はBool
                self.label.text = text
            })
            .disposed(by: disposeBag)
        
        textField.rx.text
            .bind(to: label.rx.text) // .bind の部分が .drive と同じです
            .disposed(by: disposeBag)
    }
}

上で2つ同じ処理をしているコードがあります。

vc.swift

        textField.rx.text.orEmpty.asDriver()
            .drive(onNext: { [unowned self] text in
                // 入力するたびにこの処理が走る
                print("text: \(text)")
                print("isEditing: \(self.textField.isEditing)") // self.textField.isEditing はBool
                self.label.text = text
            })
            .disposed(by: disposeBag)

        textField.rx.text
            .bind(to: label.rx.text) // .bind の部分が .drive と同じです
            .disposed(by: disposeBag)

この部分です。 僕にとっては同じ処理なのに2つの異なる書き方がある時点で勘違いが起きてしまう理由になりそうですが、 このように書くことができてしまいます。 .bindはどちらかというとRxを使ったAndroidに近い書き方かなという印象です。

APIから取得してごちゃごちゃとしたい場合は上の.drive(onNext: { [unowned self] text inなのかなと思います。

逆に言えば、 上記の2つの書き方のどちらかでUITextFieldとUILabelを連携できるようになるということでそれはそれで便利ではあります。