【Swift】Compositinal Layouts を複数の型に適応させる方法
こんにちは、しょーです。
前回、iOS13からのCollectionViewに使用できるCompositionalLayoutsのやり方を説明しました。
iOS13のCollectionView、CompositionalLayoutsでモダンにレイアウトする
今回は、複数のデータ型を一つのCollectionViewに適応させる(Multiple data types)ために一捻りさせないといけないので、そのTipsを紹介したいと思います。
行ってみましょう。
複数のデータ型を適応させるとは?
詳しくは上記のリンクで確認して欲しいのですが、CompositionalLayoutsで作成した各複数セクションを組み立てる場合、
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
というメソッドを使用してセクションを組み立てて行く必要があります。
struct ItemA: Hashable {
let id: Int
static func == (lhs: Item, rhs: Item) -> Bool {
return lhs.id == rhs.id
}
}
let itemAs: [ItemA] = {
ItemA(id: 0),
ItemA(id: 1),
ItemA(id: 2),
ItemA(id: 3)
}
let itemAs2: [ItemA] = {
ItemA(id: 4),
ItemA(id: 5),
ItemA(id: 6),
ItemA(id: 7)
}
snapshot.appendSections([Section.applianceHorizontal])
snapshot.appendItems(itemAs)
snapshot.appendSections([Section.article])
snapshot.appendItems(itemAs2)
return snapshot
ですが、UICollectionViewDiffableDataSource や NSDiffableDataSourceSnapshot には一つの方しか指定できないため、snapshotで別々のデータ型を挿入したい場合困難になります。
ここのデータ型を、今回は複数対応できる型を作成して突っ込んでいきます。
enum:Hashable で解決する
そのような場合はenumを利用すると便利です。
利用する構造体はHashableに基づいている必要がありますが、挿入したい複数の型を取りまとめるHashableに適合したenumを作成します。
enum DiffableDatas: Hashable {
case itemA(ItemA)
case itemB(ItemB)
}
struct ItemA: Hashable {
let id: Int
static func == (lhs: Item, rhs: Item) -> Bool {
return lhs.id == rhs.id
}
}
struct ItemB: Hashable {
let id: Int
static func == (lhs: Item, rhs: Item) -> Bool {
return lhs.id == rhs.id
}
}
let itemAs: [ItemA] = {
ItemA(id: 0),
ItemA(id: 1),
ItemA(id: 2),
ItemA(id: 3)
}
let itemBs: [ItemB] = {
ItemB(id: 0),
ItemB(id: 1),
ItemB(id: 2),
ItemB(id: 3)
}
この enum DiffableDatas を型として当てはめることにより、snapshot生成時にcaseに書いてある型を適合させて使用することでできます。
private lazy var dataSource: UICollectionViewDiffableDataSource<Section, DiffableDatas>! = nil
private func snapshotForCurrentState() -> NSDiffableDataSourceSnapshot<Section, DiffableDatas> {
var snapshot = NSDiffableDataSourceSnapshot<Section, DiffableDatas>()
snapshot.appendSections([Section.firstSection])
let itemsA = itemsAs.map { DiffableDatas.itemA($0) } // itemsA: [DiffableDatas] としてデータが入っている
snapshot.appendItems(itemsA)
snapshot.appendSections([Section.secondSection])
let itemsB = itemsBs.map { DiffableDatas.itemB($0) } // itemsB: [DiffableDatas] としてデータが入っている
snapshot.appendItems(itemsB)
return snapshot
}
終わりに
今回は前回に引き続きCompositionalLayoutsのお話でした。
このようなTipsを知っていると、さらに汎用性のあるCollectionViewを作成できるかと思います!
今日はこんなところです!
以上お疲れっす!
じゃーな!
ディスカッション
コメント一覧
まだ、コメントがありません