RxSwiftでUITableViewのセルをタップした時にバインディングされているitemのmodelの情報を取得する
概要
今回はRxSwiftを使ってUITableViewで表示されたセルのitemをタップした時にitemのmodelの情報を取得する方法について解説します。
前回の
と似てるようで実は違ったりします。
この方法によりリスト表示のセルをタップして画面遷移させたい時に値を渡す実装が可能になります。
開発環境について
Xcode: 10.1
Swift: 4.2
RxSwift: 4.4.0
RxCocoa: 4.4.0
storyboardの配置
前回の記事のstoryboardを拝借しますのでその続きになります。
ここからstoryboardを編集していきます。
今回は画面遷移ように詳細画面を追加するのでDetail.storyboard
のstoryboardのファイルを追加して新しいViewControllerを配置させます。
この新しいViewControllerのクラスをDetailViewController
とします。
DetailViewController.swift
import UIKit class DetailViewController: UIViewController { var nameString: String? override func viewDidLoad() { super.viewDidLoad() self.title = nameString } }
となります。
そして、プッシュ遷移にしたいので最初の画面のリスト一覧画面にはNavigationViewControllerを配置させます。
このようになります。
storyboard など新しいファイルの追加に関してはグーグル先生に任せたいので省略します。
storyboardの配置の解説は以上になります。
ソースコードの編集
やっとここからViewController.swift
のソースコードに追加のコードを書きます。
ViewController.swift
import UIKit import RxCocoa import RxSwift class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! let data = Observable<[CustomCellModel]>.just([ CustomCellModel(name: "山田花子", email: "hanako@gmail.com"), CustomCellModel(name: "田中太郎", email: "taro@gmail.com"), CustomCellModel(name: "石田真一", email: "shinichi@gmail.com") ]) var disposeBag = DisposeBag() override func viewDidLoad() { super.viewDidLoad() // CustomCellのNibファイルの登録 tableView.register(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "CustomTableViewCell") data.bind(to: tableView.rx.items(cellIdentifier: "CustomTableViewCell", cellType: CustomTableViewCell.self)) { row, element, cell in // row: Int アイテムのインデックス // element: Item(CustomCellModel) アイテムのインスタンス // cell: CustomCell セルのインスタンス // ここでセルの中身を設定する cell.nameLabel.text = element.name cell.emailLabel.text = element.email } .disposed(by: disposeBag) // tableViewのセルをタップした時にcellにバインディングされているデータを取得してハンドリング tableView.rx.modelSelected(CustomCellModel.self) .subscribe(onNext: { [weak self] model in // model = CustomCellModel let storyboard = UIStoryboard(name: "Detail", bundle: nil) let detailVC = storyboard.instantiateInitialViewController() as! DetailViewController detailVC.nameString = model.name self?.navigationController?.pushViewController(detailVC, animated: true) }) .disposed(by: disposeBag) } }
tableView.rx.modelSelected(CustomCellModel.self)
のmodelSelected
がタップした時のセルのitemのモデル情報を取得する関数になります。
これをsubscribeして得られる引数のmodel
の中にindexPathに応じたCustomCellModel
が格納されています。
RxSwiftを使わない処理ならarray[indexPath.row]としてmodel情報を取得する作業が必要でしたらRxSwiftでは必要なくなります。
(その代わりそれを知っていない場合はハマる原因に繋がります。)
まとめ
UITableViewDelegateでdidSelectRowAtするときに書くような処理の部分のハンドリング方法が分かりました。
これでUITableViewの表示とタップして画面遷移したりすることができるようになりましたね。