【iOS/Swift】IGListKit サンプルの GridSectionController を一般化する

Instagram の iOS チームが開発している CollectionView を便利に扱うための OSS として IGListKit があります。リストの途中に広告や他の差込みコンテンツを入れたい時にとても便利で長年愛用しています。

とは言え SwiftUI がいい感じになってきたのであと1年くらいで IGListKit も使わなくなりそうなのだけど…。

で、今回は IGListKit のサンプルにある GridSectionController を一般化して ListSingleSectionController のように単一の Cell を簡単に扱えるクラスのマルチカラム版として作ります。と言っても ListSingleSectionControllerDelegate は作成せずに didSelectItem だけハンドリングするので簡易版ですね。

まずはコンテンツとして表示するための情報を持った GridItem を定義します(ListDiffable に準拠していればなんでもいいので割愛します)。
汎用性を考えると class ではなくて protocol にしても良いと思います。

続いてその GridItem を格納するための入れ物を用意します。このクラス自体はサンプルにあった通りの実装で名前だけ分かりづらいので Container というワードを追加しています。 ListDiffable に準拠している必要がありますのでこうなります。


これで GridItemContainer が GridItem のリストを持っているので、ListSectionController で適切に numberOfItems() を override すれば GridItem が Grid 表示されるようになります。そのための SectionController 実装はこんな感じです。


GridSectionControllerListSingleSectionController の実装を見ていただければわかる通り、2つを掛け合わせただけです。私は使わないので delegate と storyboard は省略しています。

使い方は ListSingleSectionController とほぼ同じく、ItemCell という Cell を表示する場合の使用例は以下のようになります。

ポイントは objects(for:) にて GridItemContainer のリストを返す点と、sizeBlock で利用する側の都合で分割数を自由に変更できる点でしょうか。self をキャプチャする場合は適切に weak self なりして循環参照対策を行ってください。

以上です。