#はじめに
前回
今回は、UITableViewとRxSwiftをバインドしてみたいと思います。
ここでバインドしていますね。element
にItem
の情報が入ってきます
items.bind(to: tableView.rx.items(cellIdentifier: "cell")) { row, element, cell in
cell.textLabel?.text = element.name
cell.backgroundColor = element.color
}
#カスタムセルを使う場合
カスタムセルを使う場合は、カスタムセルをテーブルビューに登録し、bindの中を以下のように変更します。
cellType
で作成したカスタムセルを指定しています。
items.bind(to: tableView.rx.items(cellIdentifier: CustomTableViewCell.identifier,
cellType: CustomTableViewCell.self)) { row, element, cell in
cell.configure(item: element)
}
.disposed(by: disposeBag)
セルは以下のようにしました。
final class CustomTableViewCell: UITableViewCell {
@IBOutlet private weak var nameLabel: UILabel!
static var identifier: String { String(describing: self) }
static var nib: UINib { UINib(nibName: String(describing: self), bundle: nil) }
func configure(item: Item) {
nameLabel.text = item.name
backgroundColor = item.color
}
}
#複数のカスタムセルをIDによって分けたい場合
セルをクロージャの中で生成します。
isEnded
は例として、書きました。終わっている時と終わっていない時で表示させるセルを分ける(IDによって)場合を想定しています。
items.bind(to: tableView.rx.items) { tableView, row, element in
if isEnded {
let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.identifier) as! CustomTableViewCell
cell.configure(item: element)
return cell
} else {
let cell2 = tableView.dequeueReusableCell(withIdentifier: CustomTableViewCell2.identifier) as! CustomTableViewCell2
cell2.configure(item: element)
return cell2
}
}
.disposed(by: disposeBag)
#自作DataSourceを使う場合
こちらは少しだけ、難易度が上がります。
テーブルビューのdidSelectedRowAt
などを実装したいってなった時に使います。
let dataSource = MyDataSource()
items.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
final class MyDataSource: NSObject, UITableViewDataSource, RxTableViewDataSourceType {
typealias Element = [Item]
var items = [Item]()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.identifier,
for: indexPath) as! CustomTableViewCell
let item = items[indexPath.row]
cell.configure(item: item)
return cell
}
func tableView(_ tableView: UITableView, observedEvent: Event<[Item]>) {
Binder(self) { dataSource, element in
guard let items = element.element else { return }
dataSource.items = items
tableView.reloadData()
}
.onNext(observedEvent)
}
}
データソースクラスを作り、NSObject
, UITableViewDataSource
, RxTableViewDataSourceType
の三つに準拠させる。
RxTableViewDataSourceType
はtableView(_ tableView: UITableView, observedEvent: Event<[Item]>)
を使うための、プロトコルです。
これを準拠させることにより、tableView(_ tableView: UITableView, observedEvent: Event<[Item]>)
には、データがオブザーバーにやってきたときの処理を記述します。
今回の例では、items
を更新してtableView
をリロードし、描画する処理を記述しています。
そして、onNext()
でイベントを流します。
DataSourceを自作する場合の全体のコードを上げておきますGitHub
#おわりに
参考記事