ブロックチェーン・AI・システム開発の株式会社INDETAIL

iOS UICollecionViewFlowLayout でカスタムレイアウトを作ろう ~ Swift版

2015.06.29
amitan

※2017.07.31追記: 「MOREMALL(モアモール)」事業、サービス終了のお知らせ

初めまして、Objective-C未経験Swift歴6ヶ月のamitanです。
WWDC2015 にてSwift2.0オープンソース化が発表されて、テンションMAXです!!

UICollectionViewはiOS 6.0で追加された、 grid形式で表示可能なViewです。
今回は、MOREMALLアプリでも使用されているUICollecionViewFlowLayoutを継承したお手軽カスタマイズ方法をご紹介します。

UICollectionViewでのアニメーション方法についてはこちらからどうぞ。

カスタムレイアウトの作成

列数及び縦横の長さ、行列の位置を指定することで、UICollectionViewに描画ができるカスタムレイアウトを作成します。
ソースコードはgithubにあります。

開発環境

Xcode 6.3.2
iOS 8.3
Swift 1.2

UICollectionViewFlowLayoutサブクラスの作成

UICollecionViewFlowLayoutを継承したクラスを作成します。
以下メソッドをオーバーライドして実装します。

prepareLayout()

レイアウトの事前計算を行うメソッドです。

今回は、画面幅から1辺の長さを算出し、それに基づきRect値を算出しています。
要素全てのRect値をsectionCellsに格納し、コンテンツサイズの計算も行っています。

collectionViewContentSize()

コンテンツサイズを返却します。

正しいコンテンツサイズを返却しない場合、スクロールされなくなるので注意してください。

layoutAttributesForElementsInRect(rect: CGRect)

引数で与えられた範囲内に表示される要素のレイアウト情報UICollectionViewLayoutAttributesの配列を返却するメソッドです。

表示範囲に含まれている要素全てをCGRectIntersectsRectで計算し、返却しています。

layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath)

引数に与えられたNSIndexPath に対応するレイアウト情報UICollectionViewLayoutAttributesを返却するメソッドです。

UICollectionViewLayoutAttributesのframeに対応する要素のRect値を格納し返却しています。

storyboardの設定

Main.storyboardにCollectionViewを設追加し、Custom ClassにUICollecionViewFlowLayoutを継承したクラスを設定しています。
storyboardの設定

UICollecionViewControlelrの実装

UICollectionViewControlelrを継承したクラスを作成します。
UICollectionViewControlelrの実装方法は今回は割愛いたします。

viewDidLoadメソッドで作成したCustomCollectionViewFlowLayoutに対して、列数及び縦横の長さ、行列の位置を設定しています。
これで実装完了です。

サンプル実行結果

サンプル実行結果

まとめ

表示位置の計算をするだけで、比較的簡単にカスタムレイアウトが作成できました。
セクションごとにレイアウトを変えたり、UICollectionViewLayoutAttributes自体をカスタマイズしたり色々なレイアウトが楽しめそうですね。

良いSwiftライフを~

参考サイト

Apple UICollectionViewFlowLayout Class Reference
Apple Collection View Programming Guide for iOS/Creating Custom Layouts
Apple Collection View Programming Guide for iOS/Using the Flow Layout

amitan

[主な職種:エンジニア] Android・iOSアプリエンジニア。 サーバーサイドもちらほら。 問題解決としての技術活用及び取捨選択ができるエンジニア目指して日々奮闘中。

「いいね」ボタンを押すと、最新情報をすぐに確認できます。