【Swift】RxDataSourcesを使ってみた。
はじめに
RxSwift学習中のHanagasakiです。UITableViewのデータバインディングについて、深堀したいと感じたので、動画や技術記事を拝見し学んだことを纏めました。
使用環境
● OS:macOS Big Sur 11.3.1
● Xcode:13.2.1
● Swift:5.4
● RxSwift:6.5.0
● RxCocoa:6.5.0
● RxDataSources:5.0.0
RxDataSourcesって?
RxDataSourcesはRxSwiftの性質を持ったUITableViewとUICollectionViewのDataSourceのライブラリです。
RxDataSourcesを使いたい理由は、UITableViewとUICollectionViewのデータバインディングが容易に出来るからです。
つまり、UIイベントの受け取り(delete、insert、move)がこのライブラリを使うことで、簡単に実装が出来るということです。
ソースコード
今回、ソースコードのみでUIを作成したので、.storyboardファイルと.xibファイルは説明しません。
ViewController.swift
// ViewController.swift
import UIKit
import RxSwift
import RxCocoa
import RxDataSources
class ViewController: UIViewController {
/// セクションとセルの値を入れる。
var items = BehaviorRelay(value:
[SectionModel(header: "今季",
items: [Anime(name: "明日ちゃんのセーラ服")])])
let disposeBag = DisposeBag()
/// テーブルビュー
let tableView: UITableView = {
let tableView = UITableView()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
return tableView
}()
/// セル
let cell: UITableViewCell = {
let cell = UITableViewCell()
return cell
}()
/// データソース
let dataSource = RxTableViewSectionedReloadDataSource<SectionModel>(configureCell: {
ds, tv, ip, item in
let cell = tv.dequeueReusableCell(withIdentifier: "cell", for: ip)
cell.textLabel?.text = item.name
cell.tintColor = .black
return cell
},
titleForHeaderInSection: {
ds, index in
return ds.sectionModels[index].header
})
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(tableView)
lauout()
setupTableView()
}
/// データバインディング
func setupTableView() {
items
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
}
/// tableViewのレイアウトを調整。
func lauout() {
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.backgroundColor = .white
tableView.separatorColor = .black
tableView.separatorInset = .zero
let top = tableView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0)
let trailing = tableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0)
let leading = tableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0)
let bottom = tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0)
NSLayoutConstraint.activate([leading, trailing, top, bottom])
}
}
Anime.swift
// Anime.swift
import Foundation
struct Anime {
var name: String
}
SectionModel.swift
// SectionModel.swift
import Foundation
import RxDataSources
struct SectionModel {
var header: String
var items: [Anime]
}
extension SectionModel: SectionModelType {
init(original: SectionModel, items: [Anime]) {
self = original
self.items = items
}
}
完成したUI
ViewController.swiftの変数items配下のSectionModelの値を加えれば、UI側に反映されます。
var items = BehaviorRelay(value:
[SectionModel(header: "今季",
items: [Anime(name: "明日ちゃんのセーラ服")])])
おわりに
最後まで読んで下さり、ありがとうございます。
今回は、RxDataSourcesでオブジェクトライブラリを使わずに、データバインディングしてみました。
慣れていないと読みにくいですが、慣れて仕舞えばソースコードのみで、UIイベントの受け取りが出来る様になるので、是非、使ってみて下さい。
参考文献
この記事が気に入ったらサポートをしてみませんか?