[Swift]UICollectionViewの進化:Diffable Data Source編
前回
CollectionViewの構築方法の変更点として、
前回記事ではLayout
に関して記載しました。
この記事ではData Source
に関する変更点をまとめています。
Layout
に関しての前回記事はこちら
記事内で参考資料としているWWDCのスライド資料です。
Data Source
これまで使用されているUICollectionViewDataSource
は、
以下のテンプレのようにシンプルかつ柔軟性のある使い方が出来ます。
// MARK: UICollectionViewDataSource
func numberOfSections(in collectionView: UICollectionView) -> Int {
return models.count
}
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return models[section].count
}
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier,
for:indexPath)
// configure cell
return cell
}
ただこちらも1点大きな問題を抱えていました。
アプリが複雑な作りになっていくほど、
UIの更新を生成するのは困難な場合があるという問題です。
具体的な内容が公式で挙げられてますので見てみましょう。
①numberOfItemsInSection
でUI側からdata Source
に必要なセルの数を要求します。
②APIのレスポンス等からUIの更新を行おうとします。
③クラッシュ
このクラッシュ原因の内容としては、
performBatchUpdates
を実行する前と後で、
UICollectionViewの更新でsectionの数が変わります。
その際controller
とUI側でsectionの数をイコールにしておく必要があるのです。
この解決策として登場したのが、Diffable Data Source
です。
Diffable Data Source
UICollectionViewDataSource
の課題として前途しました、
UIの更新時に使用されるperformBatchUpdates
から、
apply
というメソッドを使うことに変更することで、課題の解消を試みます。
Diffable Data Source
で重要となる概念として、Snapshots
というものがあります。
こちらをまず解説していきます。
Snapshots
UI状態の真偽を持ち、
IndexPathsは不要で、セクションとアイテムで一意の識別子(Identifier)を使用します。
apply
メソッドを使いUI更新を適用させます。
どのような流れなのか以下の図を見ながら解説します。
- Snapshotの構築(
Current Snapshot
) - UI更新したい内容の新しいSnapshotを作成(
New Snapshot
) -
apply
メソッドでUIに適用する
Snapshotsの構築方法は例として以下の図のようになります。
Diffable Data Sourceの感想
performBatchUpdates
でのクラッシュへの解消、
またSnapshotsというUI状態の持つクラスの登場で、
最初のうちは慣れが必要ですが、
よりシンプルながら複雑なUIの更新が安全に出来るようになったと思います。
Discussion