UITableViewDiffableDataSourceでできること
UITableViewDiffableDataSourceは以下の2つの整合性を担保してくれます。
- UITableViewのデータソース
- UITableViewのCell表示とアニメーション
これにより、UITableViewのよくあるクラッシュ要因であるCellの追加・削除・移動時のデータソースとCell表示アニメーションの不整合を防ぐことができるようになります。
iOS 13 以上がターゲットのプロジェクトではよほどのことがない限りUITableViewDiffableDataSourceを使うのがおすすめです。
実装例
class MyTableViewController: UITableViewController {
// Hashableに準拠したSection・Item用の型を用意。
enum Section: CaseIterable {
case top
case main
}
struct Item: Hashable {
let title: String
let detail: String
}
// dataSourceを用意。
private lazy var dataSource: UITableViewDiffableDataSource<Section, Item> = {
let dataSource = UITableViewDiffableDataSource<Section, Item>(tableView: tableView) { (tableView, indexPath, item) -> UITableViewCell? in
let cell = tableView.dequeueReusableCell(withIdentifier: "MyIdentifier", for: indexPath)
cell.textLabel?.text = "\(item.title) \(item.detail)"
return cell
}
// アニメーション方式を指定。
dataSource.defaultRowAnimation = .fade
return dataSource
}()
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyIdentifier")
// tableViewのdataSourceに指定。
tableView.dataSource = dataSource
// 表示したいデータをsnapshotに入れてdataSourceに反映する。
// snapshotは現在のdataSourceを元に作ることもできる。
// `var snapshot = dataSource.snapshot()`
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections(Section.allCases)
snapshot.appendItems([Item(title: "title", detail: "detail")], toSection: .main)
dataSource.apply(snapshot)
}
}
環境
Xcode 11.1
Swift 5