RxSwift CombineLatestで3つのvalueを監視する


背景

三つのTextFieldの値を監視して、全てに文字の記入などがあれば、navigationbarのBarButtonのisEnabledのStatusをtrueに変更するということをやりたいと考えました。そこで、 combinelatestを使おうと思ったのですが、3つのobservableな値を監視して、結果を返すようなexmpleがあまり見つかりませんでした。

開発環境

Swift 4.2 ~
RxSwift 4.2 ~

方法

ViewModel

import RxSwift

class ViewModel {
  let name = Varible<String>("")
  let userID = Varible<String>("")
  let userPassword = Varible<String>("")
  let shouldSubmit: Observable<Bool>

  init() {
    self.shouldSubmit = Observable
      .combineLatest(name.asObservable(), userID.asObservable(), userPassword.asObservable()) {
        (name, userID, userPassword) in
         var result = false
         if 0 < name.cout && name.count < 20 {
           if 6 < userID.count && userID.count < 15 {
              if 8 < userPassword.count && userPassword.count < 16 {
                result = true
              }
           }
         }
         return result
      }
  }
}

ViewController

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {

  @IBOutlet weak var nameTextField: UITextField!
  @IBOutlet weak var userIDTextField: UITextField!
  @IBOutlet weak var userPasswordTextField: UITextField!

  private let viewModel = ViewModel()
  private let disposeBag = DisposeBag()

  override func viewDidLoad() {
    super.viewDidLoad()
    let barButton = UIBarButtonItem(title: "追加", style: .done, target: self, action: #selector(self.add))

    // setup bind
    self.nameTextField.rx.text.orEmpty
      .bind(to: self.viewModel.name)
      .disposeBag(by: self.disposeBag)
    self.userIDTextField.rx.text.orEmpty
      .bind(to: self.viewModel.userID)
      .disposeBag(by: self.disposeBag)
    self.userPasswordTextField.rx.text.orEmpty
      .bind(to: self.viewModel.userPassword)
      .disposeBag(by: self.disposeBag)
    self.viewModel.shouldSubmit
      .bind(to: barButton.rx.isEnabled)
      .disposed(by: self.disposeBag)
    self.navigationItem.rightBarButtonItem = barButtton
  }
}

参考文献