こんばんは!
RxSwift (RxCocoa)を使ってモデル←→ビューのお互いの更新を伝え合う双方向データバインディングをやってみます。
SwiftBond では双方向データバインディングがサポートされているのですが RxSwiftのドキュメントにはそのような記述はなく、綺麗に書く方法ないかな〜とExamplesを眺めていたらそれっぽいものを見つけたのでご紹介します。
やってること
- 登場人物
- ラベル
- 最新の値を表示し続ける
-
テキストフィールド ←こいつに双方向bindを実装します
- 最新の値を表示し続ける
- 値を入力できる
- ボタン
- 値を初期値に変更できる
- ラベル
このUIにおいて、
- テキストフィールドで入力した内容が即時ラベルに反映される。
- ボタンの押下で書き換わった内容が即時テキストフィールドに反映される。
という点において双方向のデータバインディングを実現してみます。
Before
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
private var item = Variable<String?>("Hello!")
private let disposeBag = DisposeBag()
@IBOutlet weak var label: UILabel!
@IBOutlet weak var textField: UITextField!
@IBAction func resetButtonHandler(_ sender: UIButton) {
item.value = "Hello!"
}
@IBAction func textFieldHandler(_ sender: UITextField) {
item.value = sender.text
}
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
private func setup() {
// モデルからビューへ
item.asObservable().bind(to: textField.rx.text).disposed(by: disposeBag)
// ビューからモデルへ
textField.rx.text.subscribe(onNext: { [weak self] text in
self?.item.value = text
}).disposed(by: disposeBag)
// 最新の値をラベルで表示しておく
item.asObservable().bind(to: label.rx.text).disposed(by: disposeBag)
}
}
ここで Bidirectional Operator <->
の登場です。
左辺にビュー、右辺にモデルが来るように書きます。
さらにそのままだと返り値が未使用と言われるので _ =
を先頭につけておきます。
(一応例にもそう書いてあったのですが、万が一メモリリークの危険性踏んでたら教えて頂きたく...! )
After
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
private var item = Variable<String?>("Hello!")
private let disposeBag = DisposeBag()
@IBOutlet weak var label: UILabel!
@IBOutlet weak var textField: UITextField!
@IBAction func resetButtonHandler(_ sender: UIButton) {
item.value = "Hello!"
}
@IBAction func textFieldHandler(_ sender: UITextField) {
item.value = sender.text
}
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
private func setup() {
_ = textField.rx.text <-> item // ここ(´∀` )
item.asObservable().bind(to: label.rx.text).disposed(by: disposeBag)
}
}
ユーザID+パスワードや、住所氏名年齢電話番号・・・のような設定するコンポーネントが多い画面で活躍してくれそうです!
だんだんRxSwiftが面白くなってきた今日このごろです おやすみなさい。