39
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

UICollectionViewDelegateFlowLayoutでセルの大きさやセル同士の間隔などを個別に設定する

Last updated at Posted at 2018-04-23

UICollectionViewFlowLayoutでセルの大きさやセル同士の間隔などを設定するでは、UICollectionViewFlowLayoutオブジェクトのプロパティを変更することによってセルの大きさやセル同士の間隔が設定できることを確認しました。

UICollectionViewFlowLayoutオブジェクトの設定は全てのセルに対して適用されます。
各セル個別に大きさを設定したり、セクションごとに行間の長さや余白の大きさを設定するには、UICollectionViewDelegateFlowLayoutプロトコルを実装します。

ここではUICollectionViewDelegateFlowLayoutを実装し、レイアウトがどう変わるかを見ていきます。

なお、本記事では説明に必要な箇所のコードのみ掲載しています。
ベースとなる実装については以下の記事を参照してください。

UICollectionViewを必要最低限のコードで実装してみる

個別にセルの大きさを設定する

個別にセルの大きさを設定するには、UICollectionViewDelegateFlowLayoutプロトコルのcollectionView:layout:sizeForItemAt:メソッドを実装します。

例えば奇数番目のセルのみ幅を100にするという実装をしてみます。
※コード上はインデックスが0から始まるため、偶数番目のセルの幅を100にしています。

extension ViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let oddEven = indexPath.row % 2
        let width: Int

        if oddEven == 0 {
            width = 100
        } else {
            width = 50
        }

        return CGSize(width: width, height: 50)
    }
}

image.png

1番目、3番目...と、奇数番目のセルの幅を変更できています。

最終行だけレイアウトがズレていますが、これは1、2行目はセル同士の間隔が自動調整されて広がっているのに対し、最終行はデフォルトの間隔が使用されているためです。
なぜこのような挙動になるのかは、こちらを参照してみてください。

セクションごとにセル同士の間隔の長さを変更する

セクションごとにセル同士の間隔の長さを変更するには、UICollectionViewDelegateFlowLayoutプロトコルのcollectionView:layout:minimumInteritemSpacingForSectionAt:メソッドを実装します。

セクションごとで違いを見たいので、セクション数を2に設定します。
最初のセクションでは間隔の長さを50に設定し、2つ目のセクションでは長さを10に設定します。

extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 2
    }
}

extension ViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        if section == 0 {
            return CGFloat(50)
        } else {
            return CGFloat(10)
        }
    }
}

image.png

セクション間の余白がないのでわかりづらいですが、上半分は間隔が広く、下半分は間隔が狭くなっているのがわかります。

セクションごとに行間の長さを変更する

セクションごとに行間の長さを変更するには、UICollectionViewDelegateFlowLayoutプロトコルのcollectionView:layout:minimumLineSpacingForSectionAt:メソッドを実装します。

セクションごとで違いを見たいので、セクション数を2に設定します。
最初のセクションでは行間の長さを50に設定し、2つ目のセクションでは長さを10に設定します。

extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 2
    }
}

extension ViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        if section == 0 {
            return CGFloat(50)
        } else {
            return CGFloat(10)
        }
    }
}

image.png

上半分は行間が広く、下半分は行間が狭くなっているのがわかります。

セクションごとの余白を変更する

セクションごとの余白を変更するには、UICollectionViewDelegateFlowLayoutプロトコルのcollectionView:layout:insetForSectionAt:メソッドを実装します。

セクションごとで違いを見たいので、セクション数を2に設定します。
最初のセクションでは余白を上下左右24を設定し、2つ目のセクションでは余白なしにします。

extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 20
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 2
    }
}

extension ViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        if section == 0 {
            return UIEdgeInsets(top: 24, left: 24, bottom: 24, right: 24)
        } else {
            return UIEdgeInsets.zero
        }
    }
}

image.png

最初のセクションには余白があり、2つ目のセクションには余白がないことが確認できます。

39
27
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?