RxSwiftでUIPickerViewとUITextFieldのテキストをバインドする
最近RxSwiftの勉強をしていて思いついたバインドをやってみる。
UIPickerView
からデータを選択し、そのデータをUITextField
のテキストにセットするものである。
UIPickerView
をUITextField
の入力として使用する
まずUIPickerView
をUITextField
の入力のViewとして使用するには、UITextField
のプロパティinputView
にUIPickerView
のインスタンスを代入するだけでよい。
textField.inputView = UIPickerView()
ただ、これだけではUIPickerView
のdataSource
が実装されていないので、選択するデータがない。また、UIPickerView
から選択したときのイベントをdelegate
でハンドリングし、そのデータをUITextField
のテキストにセットする必要がある。
今回はUIPickerView
のdataSource
とdelegate
を用いての実装は省略するが、まあ面倒である。そこで本題のRxSwift
を用いた実装を次に紹介する。
RxSwiftでUIPickerView
とUITextField
をバインドする
class ViewController: UIViewController { @IBOutlet weak var strTextField: UITextField! let disposeBag = DisposeBag() override func viewDidLoad() { super.viewDidLoad() let strPickerView = UIPickerView() strTextField.inputView = strPickerView // strsをstrPickerViewのデータ(タイトル)としてバインド let strs = ["abc", "def", "ghi"] Observable.just(strs) .bind(to: strPickerView.rx.itemTitles) { _, str in return str } .disposed(by: disposeBag) // strPickerViewから選択したデータ(タイトル)をstrTextFieldのテキストにバインド strPickerView.rx.modelSelected(String.self) .map { strs in return strs.first } .bind(to: strTextField.rx.text) .disposed(by: disposeBag) } }
比較するべきdataSource
とdelegate
を用いた実装が今回はないが、上記のコードを見るだけでも簡潔に書けていることがわかると思う。
まとめ
bind()
メソッドでデータをバインドできるのは便利だと感じた。また、modelSelected()
メソッドがジェネリクスを用いて、データとしてバインドした任意の型を取得できるのも良いと感じた。UIPickerViewDelegate
のpickerView(_:didSelectRow:inComponent:)
は選択したデータの行などしか取得できないので、それに比べると便利だと思う。
今記事のコードを用いたサンプルをgithubにあげておく。