UIKit ~UICollectionView~ 編

はじめに

今回はUICollectionViewについて紹介します。

使い方は前回の基本的にUITableViewとほぼ同じような実装になります。
先にそちらを見ることをおすすめします。

UICollectionViewとは

UICollectionViewはサムネイル表示などに使います。
UITableViewは1列×N行のリストでしたがM列×N行のリストになります。

標準の写真アプリなどをイメージするとわかりやすいかと思います。

実装方法

それでは早速実装方法について説明していきます。
基本手順はUITableViewと同じです。

新規プロジェクトを立ち上げて実装していきましょう。

Storyboard

まずMain.storyboardUICollectionViewを配置します。
ボタンなどと同様に以下のように検索しStoryboard上に配置します。

オートレイアウトを設定します。
画面いっぱいに表示するので上下左右のマージンを0とします。
このUICollectionViewの領域にリストが表示されます。

四角いUIはUICollectionViewCellです。
UITableViewCellUICollectionView版です。

セルにIDを設定します。
追加されたUICollectionViewCellを選択しAttributes Inspectorの[Identifier]に任意のIDを設定してください。
以下の例ではSampleCellと設定しています。

これでStoryboardの設定は完了です。

ここで設定したセルはUITableViewと同じで表示するセルの雛形です。
実際にはこの雛形を複製していき、複数のセルを表示していきます。

UICollectionViewをViewControllerに紐付ける

次はUICollectionViewをコードから操作できるようにViewControllerとアウトレット接続します。
接続の方法はボタンやラベルと同様です。

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var collectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

表示するセルを設定する

それでは表示するセルを設定していきます。

表示するセルの設定はDelegateDataSourceを使って設定します。
Delegateについてはこちらで簡単に説明しています。(DataSourceも似たようなものです)
もしわからなければこういう風に設定するんだという理解で今は構いません。

まずViewControllerUICollectionViewDataSourceUICollectionViewDelegateを継承します。
(ちなみに今回の説明ではDelegate側のメソッドは使わないのでなくても構いません)

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
    @IBOutlet weak var collectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

するとUITableViewDataSourceのときと同じように以下のエラーが表示されます。
Type 'ViewController' does not conform to protocol 'UICollectionViewDataSource'

今回実装する必須メソッドは以下となります。

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int)
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)

やはり一緒ですね。
それぞれセル数と表示するセルを設定するためのメソッドです。

それぞれ設定してあげます。
またdelegatedataSourceにのオブジェクトとしてselfを設定してあげます。

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {

    @IBOutlet weak var collectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.collectionView.delegate = self
        self.collectionView.dataSource = self
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = self.collectionView.dequeueReusableCell(withReuseIdentifier: "SampleCell", for: indexPath)
        // 背景色を設定しておく
        cell.backgroundColor = UIColor.blue

        return cell
    }
}

これでUICollectionViewの設定は完了です。
実行してみましょう。

セルが10個表示されました。

ここまでが最も基本的なUICollectionViewの表示の仕方です。

セルのサイズを変更する

セルのサイズは当然自由に変更できます。

サイズやレイアウトの変え方はいくつかありますが今回はUICollectionViewFlowLayoutを使った方法を紹介します。
(他にはUICollectionViewDelegateFlowLayoutを使う方法もあります)

viewDidLoadを以下のように編集してください。

override func viewDidLoad() {
    super.viewDidLoad()
    
    self.collectionView.delegate = self
    self.collectionView.dataSource = self

    // レイアウトの調整
    let flowLayout = UICollectionViewFlowLayout()
    flowLayout.itemSize = CGSize(width: 100, height: 100)
    self.collectionView.collectionViewLayout = flowLayout
}

実行すると以下のようになります。

セルのサイズが変わりました。
flowLayout.itemSizeにはセルのサイズサイズを設定することができます。

セルのサイズを設定したflowLayoutオブジェクトを
self.collectionView.collectionViewLayout = flowLayout
としてUICollectionViewと紐付けています。

また列数も3列となりました。
これはUICollectionViewの性質で、デフォルトではセルが収まるように均等セルを配置します。
例えば今回の場合4列になると横幅は最低でも400pt必要です。
このシミュレータの横幅のサイズは375ptなので4列では収まりません。
なので3列で表示されています。
400-375=25[pt]余るので余った分は均等にマージンとして取られています。

ですが端末サイズは大きいものだとiPadもあり、9.7inchの場合横幅が768ptとなります。
iPadで実行してみましょう。

7列となりました。
これでレイアウトとして問題ない場合はきにする必要はありませんが、常に3列で表示したいという場合があるかと思います。

そういった場合はよく端末の横幅からゴリゴリ計算して設定します。
以下の例では3列でセル同士のマージンを20とした場合の実装です。

let flowLayout = UICollectionViewFlowLayout()

let screenWidth: CGFloat = UIScreen.main.bounds.width
let cellColumn: CGFloat = 3
let margin: CGFloat = 20

let cellWidth = (screenWidth - (cellColumn - 1) * margin) / cellColumn
let cellHeight = cellWidth

flowLayout.itemSize = CGSize(width: cellWidth, height: cellHeight)
self.collectionView.collectionViewLayout = flowLayout

ただただ計算をしセルの横幅を求め設定します。
実行すると以下のように3列で表示されます。

基本的にはこのように計算で設定します。
面倒に感じるかもしれませんがある程度パターンが決まっているので慣れれば問題ありません。

UICollectionViewUITableViewの実装方法の違いとしては基本的にこのあたりのレイアウト調整でしょうか。
セルをカスタマイズする方法などはUITableViewCellと同様でUICollectionViewCellを継承したクラスを作成し、Storyboardから設定するだけなので今回は割愛します。

最後に

今回はUICollectionViewの基本的な実装方法について紹介しました。
基本的にUITableViewと同じなのでこちらの記事を参考にすれば実装できるかと思います。

UICollectionViewは汎用性が高く複雑なレイアウトを組むことも可能です。
調べながら実現したいレイアウトを作ってみてください。

今回の内容は以上です。

コメント

タイトルとURLをコピーしました