UICollectionView で UITableView のセクションヘッダー風の SupplementaryView を実装する
UICollectionView は昔なら UITableView を使って頑張って実装していようなグリッドレイアウトな UI を UITableView ライクな I/F で実装できる素敵なやつです。UITableView ライクな I/F とは言いましたが実は細かい挙動が UITableView とは違っています。UICollectionView で UITableView のセクションヘッダーのようなものを実装するには SupplementaryView を使います。でも普通に UICollectionViewFlowLayout を使っても SupplementaryView はスクロールすると Cell と同じようにそのまま通り過ぎてしまいます。UITableView のセクションヘッダーみたいに同一セクション内の場合に上端に居続けてくれません。UITableView のセクションヘッダーみたいなフローティングした(上端に張り付いたような)セクションヘッダーを実装したい。じゃあ、似たような挙動になるようにしようっていうのが今回の話です。
とりあえずググる
特にライブラリとしてまとまっているものが見つけられませんでした。(あとで調べたら vast-eng/uicollectionview-gridlayoutというのがありました。)しかし、stackoverflow で同じようなことをしたいという質問が見つかりそこから gist に上げられたコードを見つけました。
Sticky Headers at the top of a UICollectionView
やや難あり
さっきの gist ですが、確かに UITableView のセクションヘッダーみたいに同一セクション内の場合に上端に居続けてくれるのですが、全体的に位置が下がり気味。何かが違う。
どノーマルの UICollectionViewFlowLayout を使ったものがこちら
gist のコードをそのまま適用したのがこちら
修正
ずれる理由は UICollectionViewFlowLayout
の sectionInset
の値が考慮されていませんでした。修正後のコードはこちら。
UIEdgeInsets sectionInset = self.sectionInset;
origin.y = MIN(
MAX(
contentOffset.y + cv.contentInset.top,
(CGRectGetMinY(firstObjectAttrs.frame) - topHeaderHeight - sectionInset.top)
),
(CGRectGetMaxY(lastObjectAttrs.frame) - bottomHeaderHeight + sectionInset.bottom)
);
公開
修正したコードを UICollectionViewFlowLayout
のサブクラスとして github にあげています。もし使えそうなら使って見てください。
CSNFloatingHeaderViewFlowLayout
CocoaPods でインストールできます。
pod 'CSNFloatingHeaderViewFlowLayout', '~> 0.0'
Thank you toblerpwn.