【Delegate】CollectionViewをUIViewControllerで実装する方法を解説

CollectionViewの実装の仕方はUITableViewの実装と類似する部分が多くあるよ。そのためまずはTableViewの実装を理解してから、CollectionViewの実装を理解するようにすると頭に入ってきやすいよ そもそもCollectionViewを実装する方法は次の二通りがあるよ。

  • UIViewControllerでCollectionViewを実装する方法
  • UICollectionViewControllerでCollectionViewを実装する方法

前者のやり方の方が後者のやり方に比べて若干工数がかかるが、汎用性が高い実装をすることができるため多く使われているよ。よってこの記事では前者の方法を解説することにするよ。

UIViewController上でCollectionViewを実装する流れ

実装の流れをざっくりとリスト化すると下のようになるよ。流れとしてはUIViewControllerでTableViewを実装する方法と全く一緒だから、TableViewを理解している人は読み飛ばしてFlowLayoutの項目をみて欲しいよ。

  1. StoryboardとViewControllerの関連付け・outlet接続
  2. UIViewControllerのプロトコル拡張
  3. delegateメソッドの実装
  4. delegate・dataSourceの設定

このリストに沿って手順を説明していくよ。

下準備

  • 新しいプロジェクトを作成
  • MainViewControllerMain.storyboardの二つのファイルを作成
  • Main.storyboardにUIViewControllerを配置して、さらにその上にCollectionViewを貼り付ける
  • 「Is Initial ViewController」にチェックマークを入れる(チェックマークが入ると下画像の「→」マークが表示される)

  • 「Targets」→「Deployment Info」→「Main Interface」をMainに設定

手順1. outlet接続

以下3つの設定をStoryboard上から行います。

  • outlet接続

手順 2 プロトコル拡張とdelegateメソッドの実装

UICollectionViewDelegate,UICollectionViewDataSourceを継承するよ

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {  
}  

CollectionViewを実装するにあたって最低限必要なdelegateメソッドを2つ紹介するよ。ちなみにTableViewの実装で使ったdelegateメソッドの名前の「Rows」が「Items」に置き換わっただけで他はほとんど変わっていないよ。

numberOfItemsInSectionでcellの個数を定義する

公式ドキュメントの実装を見てみると、

func collectionView(_ collectionView: UICollectionView,   
numberOfItemsInSection section: Int) -> Int  

返り値はIntであることがわかると思うよ

cellForItemAtで描画するcellを定義する

公式ドキュメントの実装を見てみると

func collectionView(_ collectionView: UICollectionView,   
      cellForItemAt indexPath: IndexPath) -> UICollectionViewCell  

返り値はUICollectionViewCellを継承している必要があるよ

補足: 【UICollectionViewDelegateFlowLayout】Delegateを使ってCollectionViewのレイアウトを調整する

UICollectioViewDelegateFlowLayoutを継承することで、CollectionViewのレイアウトに関するdelegateメソッドを宣言できるようになるよ。主なものとしては以下の4つだよ。これはTableViewにはなかった要素なので、要注意。

  • minimumLineSpacingForSectionAt
  • minimumInteritemSpacingForSectionAt
  • sizeForItemAt
  • insetForSectionAt

順次解説していくよ。ちなみにこれらのメソッドはCollectionViewを実装する上で必ずしも宣言しなくても良いメソッドであるからオプショナルのメソッド(optional func)として定義されているよ。
またCollectionViewのレイアウトについてもっと詳しく知りたい人はUICollectionView の Layout で悩んだらを参照すると良いと思うよ

minimumLineSpacingForSectionAtでcell同士の縦の間隔を定義する

公式ドキュメントを参照するとCGFloat型を返り値に持つことがわかるよ。また引数にsectionを持っているので、switch文などでセクション毎に間隔を変更させることも可能だよ。

optional func collectionView(_ collectionView: UICollectionView,  layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat  

minimumInteritemSpacingForSectionAtでcell同士の横の間隔を定義する

公式ドキュメントを参照するとminimumLineSpacingForSectionAtと同様に、CGFloat型を返り値に持つことがわかるよ。また引数にsectionを持っているので、switch文などでセクション毎に感覚を変更させることも可能だよ。

optional func collectionView(_ collectionView: UICollectionView,  layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat  

insetForSectionAtでinsetを定義する

公式ドキュメントを参照するとUIEdgeInsets型を返り値として持つことがわかるよ。

optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets  
UIEdgeInsets

UIEdgeInsetsは四方向のプロパティを持っていて以下のように定義できるよ。詳しくは公式ドキュメントを参照

let inset = UIEdgeInsets(top: 5, left: 4, bottom: 9.0, right: 0)  

sizeForItemAtでcellのサイズを定義する

公式ドキュメント

optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize  
CGSize

CGSizeはwidthheight二つのプロパティを持つ構造体で、以下のように定義できるよ。詳しくは公式ドキュメントを参照

let size = CGSize(width: 10, height: 10) //10 x 10の正方形型  

最後までご覧いただきありがとうございました

こっちは真面目に作ってます。笑

サクっとプログラミング

iOSアプリ開発のあれこれがまとまるwebサイト