RxSwift

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

概要

UITextFieldのRxSwiftの書き方について調べてみました。
よくあるUILabelに連携してデータをバインディングする処理はまた別です。
超基本的な書き方について説明していきます。

開発環境について

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

UITextFieldの書き方について

RxSwiftのメリットであるDelegateメソッドを書く必要がないのでstoryboardとかでdelegateを接続させることが必要なくなります。
逆にdelegateを接続してViewControllerに準拠させるとアプリが落ちてしまう仕様のようなので接続させないように注意してください。

f:id:qed805:20190211115244p:plain

storyboardでの設定はこのように@IBOutletだけ接続させます。delegateは接続させないでください

ViewControllerのソースコードを以下のようになります。
コメントでどのタイミングでどの処理が走るのかを記載しています。

ViewController.swift

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
            })
            .disposed(by: disposeBag)
        
        
        textField.rx.controlEvent(.editingDidBegin).asDriver()
            .drive(onNext: { _ in
                // キーボードが表示された時に処理が走る
                print("editingDidBegin")
            })
            .disposed(by: disposeBag)
        
        textField.rx.controlEvent(.editingChanged).asDriver()
            .drive(onNext: { _ in
                // textFieldの値が変更されるたびに処理が走る
                print("editingChanged")
            })
            .disposed(by: disposeBag)
        
        textField.rx.controlEvent(.editingDidEnd).asDriver()
            .drive(onNext: { _ in
                // キーボードが閉じた時に処理が走る
                print("editingDidEnd")
            })
            .disposed(by: disposeBag)
        
        textField.rx.controlEvent(.editingDidEndOnExit).asDriver()
            .drive(onNext: { _ in
                // よくわからない
                print("editingDidEndOnExit")
            })
            .disposed(by: disposeBag)
        
        textField.rx.controlEvent(.valueChanged).asDriver()
            .drive(onNext: { _ in
                // よくわからない
                print("valueChanged")
            })
            .disposed(by: disposeBag)
    }
}

これでアプリを起動してUITextFieldを触ってみてください。

Xcodeのコンソールにprintの出力が表示されたら成功です。
UITextFieldのRxSwiftの書き方の基本形がこのようになりあとはバインディングやバリデーションが追加されると行った理解になります。

ABOUT ME
tamappe
都内で働くiOSアプリエンジニアのTamappeです。 当ブログではモバイルアプリの開発手法について紹介しています。メインはiOS、サブでFlutter, Android も対応できます。 執筆・講演のご相談は tamapppe@gmail.com までお問い合わせください。