今回はUICollectionViewControllerの使い方をメモしていきます。
Contents
UICollectionViewControllerとは
アルバムアプリがUICollectionViewControllerをもっとも意識しやすいと思います。
四角い枠が画面内にいっぱいに敷き詰められていてる状態です。
それがUICollectionViewControllerです。
あとはFacebookのタイムラインで出て来る『知り合いかも』の欄です。
横スクロールしますが、あれもUICollectionViewControllerで実装できます。
このように、UITableViewControllerのように縦リスト形式ではなく、
横や数列のリスト形式のものを実装できることがUICollectionViewControllerの特徴です。
UICollectionViewControllerの実装の流れ
まずはStoryboardを開き、
デフォルトのUIViewControllerは捨てて、
UICollectionViewControllerを配置しましょう。(is initial View Controllerにも忘れずにチェックを!)

そして、
セルにIdentifierを設定します。
- Collection view cell を選択した状態で、
- Identifierを『cell』に設定。

次にStoryboardに置いたUICollectionViewControllerに対応したファイルを作成します。
[File]↓
[New]↓
[File]
次に[Cocoa Touch Class]を選択。

次に
Class名は『CollectionViewController』
SubClass名は『UICollectionViewController』
に設定。

するとこのようなファイルが作成されるかと思います。
import UIKit private let reuseIdentifier = "Cell" class CollectionViewController: UICollectionViewController { override func viewDidLoad() { super.viewDidLoad() // Uncomment the following line to preserve selection between presentations // self.clearsSelectionOnViewWillAppear = false // Register cell classes self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier) // Do any additional setup after loading the view. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ // MARK: UICollectionViewDataSource override func numberOfSections(in collectionView: UICollectionView) -> Int { // #warning Incomplete implementation, return the number of sections return 0 } override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { // #warning Incomplete implementation, return the number of items return 0 } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) // Configure the cell return cell } // MARK: UICollectionViewDelegate /* // Uncomment this method to specify if the specified item should be highlighted during tracking override func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool { return true } */ /* // Uncomment this method to specify if the specified item should be selected override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { return true } */ /* // Uncomment these methods to specify if an action menu should be displayed for the specified item, and react to actions performed on the item override func collectionView(_ collectionView: UICollectionView, shouldShowMenuForItemAt indexPath: IndexPath) -> Bool { return false } override func collectionView(_ collectionView: UICollectionView, canPerformAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) -> Bool { return false } override func collectionView(_ collectionView: UICollectionView, performAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) { } */ }
めちゃくちゃ長いですねー、
コメントアウトされている部分のすごく多いです。
一般的によく使用されるであろうメソッドを勝手に書いてくれているんですよね。
Xcodeは本当に優秀です。。。
でも今回使うのはこの半分くらいです。笑
さっと編集していきます。
編集ポイントは二つです。
- identifierを”Cell”から”cell”に変更。
- コメントアウトの削除(あると見づらくて邪魔なので・・・)
import UIKit private let reuseIdentifier = "cell" // 『Cell』から先ほどStoryboardにて設定した『cell』に変更! class CollectionViewController: UICollectionViewController { override func viewDidLoad() { super.viewDidLoad() self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } override func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 100 } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) cell.backgroundColor = UIColor.cyan return cell } }
ここで
Storyboardに戻りましょう。
CollectionViewController.swiftをStoryboard上のUICollectionViewControllerに対応させましょう。

ここでひとまず完成です!RUNしましょう。
このような画面になれば完璧です!

コードの解説
上から見ていきましょう。
register
実はこれ必要ありません!
xibファイルを使用してUICollectionViewCellをカスタマイズする際に必要になります。
numberOfSections
これはセクションの数を決めるメソッドです。
戻り値に数を指定します。
セクションとは、セルをまとめる大枠です。
今回は1に設定しているのでセクションを感じませんが、2、3と増やしてみるとわかりやすいです!

numberOfItemsInSection
これはセルの数を決めているメソッドです。
戻り値に数を指定します。
今回は100に設定しました。
大きな数を設定すると、画面からはみ出ますが、
スクロール機能がデフォルトでついています。
cellForItemAt
おそらくこれが一番の難所です。
ここでは、セルに表示する内容を決めています。
今回はbackgroundColorを指定するだけにしていますが、
画像や、文字なんかもここで設定します。
特にややこしいのが、
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
ここですね。
なるべくシンプルに考えましょう。
ここでは、Storyboardで指定したidentifier『cell』を
withReuseIdentifierに設定します。
今回は定数reuseIdentifierに『cell』を格納していたのでこのようになりましたが、
別の書き方をするなら
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
と書くことも可能です。
以上です!