[Swift] CollectionViewの最後のセルがレイアウトバグって苦労した

タイトルの画像は全く意味ないです。バーに行った時にシャンパンが綺麗だったので撮りました。笑

Sponsored Link

ハマった現象

ズバリこれ↓

これをタイトル画像にすればよかった。なんでシャンパンになんかしたんだw

Estimate SizeがAutomaticの場合

こんな表示になったらEstimate Sizeが悪さしてる可能性が高いです。(ロード前の仮サイズみたいなものを設定しちゃっているんだと思います)

UICollectionViewのセル設定

前提として、CollectionViewはInterface Builderで設定しています。

CollectionViewで3列くらいの画像のみのViewを作成するとき、以下のようにコードを書くと思います。

import UIKit
class SomeViewController: UIViewController {
    @IBOutlet private weak var collectionView: UICollectionView!
    /// collectionViewCellのPadding
    private let sectionInsets = UIEdgeInsets(top: 10.0, left: 7.0, bottom: 10.0, right: 7.0)
    // 1行あたりのアイテム数
    private let itemsPerRow: CGFloat = 3

    override func viewDidLoad() {
        super.viewDidLoad()
        setupCollectionView()
    }

    /// collectionViewの設定
    private func setupCollectionView() {
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.register(UINib(nibName: "SomeCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "SomeCollectionViewCell")
        collectionView.register(UINib(nibName: NSStringFromClass(UICollectionViewCell.self), bundle: nil), forCellWithReuseIdentifier: NSStringFromClass(UICollectionViewCell.self))
    }
}

extension SomeViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SomeCollectionViewCell", for: indexPath)
        cell.setup(hoge: fuga)
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 5
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let paddingSpace = sectionInsets.left * (itemsPerRow + 1)
        let availableWidth = view.frame.width - paddingSpace
        let widthPerItem = availableWidth / itemsPerRow
        return CGSize(width: widthPerItem, height: widthPerItem * 1.4)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return sectionInsets
    }

    // セルの行間の設定
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return sectionInsets.left
    }
}

これだと先ほどの画像のような現象に陥る可能性があります。

何が原因だったか

ズバリ、Interface Builderで追加した際にCollectionViewFlowLayoutのMin Spacingがデフォルトで10になっていることです。これはひどいよ〜

どこの部分かというと、CollectionViewがあるViewをInterface Builderで開き、左ペインでCollectionViewFlowLayoutを選択します。

CollectionViewFlowLayoutを選択
Min Spacingに元々10が入っている

全く気づけず数時間費やしたので(他にもAPIから情報が取れないなどもあったのですが…)備忘録として記録しておきます。

もし他の方の参考になれば幸いです。

終わり

簡単な備忘録でした。

4月にメルボルンに行ってきまして、その時のことをブログにしようと思っていますが、その前にやらなきゃいけないことがありまして、手をつけられていません。

がんばります〜

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です