UICollectionViewで綺麗なグリッド表示をする

Sunday, January 31, 2016

せっかくの休日ということでだらだらしつつ、μライブラリの整理や作成をして過ごしました。
今回はUICollectionViewのレイアウト調整を簡単にするライブラリ(extension)の紹介です。


UICollectionViewで、viewの横幅を4分割した長さを1辺とする正方形のcellを綺麗に並べてグリッド表示したりするときに、
正方形の1辺の長さをいちいち計算したり、cellとcellの間やsectionInsetの値を気にしたりと面倒だったりします。
昔は決め打ちで、320px / 4 = 80px で、あとはspaceが2pxとかなら…って感じで良かったのですが、
AutoLayout、様々なサイズの端末の出現によってそれも現実的ではなくなってきました。
(完全にどの端末でもcollectionViewの横幅が固定なら別ですが)

毎回計算して適応して..ってのが面倒だったので、UICollectionViewのextensionとして実装してみました。

sample

どういったものかというと、分割数と、cellとcellの隙間の間隔を指定してあげると
いい感じにitemSize,minimum~~Spacing、sectionInsetを設定してレイアウトをリロードしてくれます。
使い方はこんな感じです。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    view.layoutIfNeeded() // レイアウトの更新前に呼ぶ必要あり
    collectionView.adaptBeautifulGrid(4, gridLineSpace: 2.0)
}

こうすると、横幅を4分割して、cellとcellの間2.0pxを考慮して綺麗に配置できるレイアウトに組み直します。
sectionInsetを追加で指定することが出来、指定がない場合は、上下左右spaceの値を入れて実行します。

また、 viewDidLayoutSubviews() に記述することで、ViewControllerの view(collectionView) のサイズが確定した後にレイアウトを行うことができるので、楽ができます。
何かをトリガーにして adaptBeautifulGrid を呼び出して更新することも可能です。

また、以下のようにすれば、回転可能なアプリで、縦画面ならグリッドを4、横画面ならグリッドを6にすることも可能です。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    view.layoutIfNeeded()

    let isLandscape = UIDeviceOrientationIsLandscape(UIDevice.currentDevice().orientation)
    let perRow = 4 + (isLandscape ? 2 : 0)
    collectionView.adaptBeautifulGrid(perRow, gridLineSpace: 2.0)
}

※特に触れていないですが、上記まではcollectionViewのscrollDirectionがVerticalの時を想定しています。 Horizontalの場合は、collectionViewの縦幅を分割します。
※明らかにspaceの値が大きすぎたり、rowの指定数が0以下の場合でレイアウト不可能な場合は何も調整せずに処理を中断します。


追記

Qiitaにもとりあえず投稿してみた。
誰かの目に止まってこれ使おうって思ってもらえればいいと願いつつ。

techSwiftiOS

Objective-C+Generics+typedef

これから