LoginSignup
3
0

More than 1 year has passed since last update.

UICollectionViewを簡単に使うためのテンプレート

Last updated at Posted at 2021-08-22

環境

swift version5.4

コード

下準備

import UIKit

extension UIView {

    /// クラス名を文字列で返す
    static var className: String { String(describing: Self.self) }
}
import UIKit

extension UICollectionView {

    func register<T: UICollectionViewCell>(type: T.Type) {
        let nib = UINib(nibName: T.className, bundle: nil)
        register(nib, forCellWithReuseIdentifier: T.className)
    }

    func dequeueReusableCell<T: UICollectionViewCell>(withReuseCell type: T.Type, for indexPath: IndexPath) -> T {
        let cell = dequeueReusableCell(withReuseIdentifier: T.className, for: indexPath) as! T
        return cell
    }
}

import UIKit

/// UICollectionViewのカラムレイアウトを作成するためのstruct
struct ColumnSetting {

    let column: CGFloat
    let verticalMargin: CGFloat
    let sideMargin: CGFloat
    let interMargin: CGFloat
    let aspectRatio: CGFloat

    /// 指定のカラム数のレイアウトを作成するための設定
    /// - Parameters:
    ///   - column: カラム数
    ///   - verticalMargin: 上下の余白。初期値0。
    ///   - outerMargin: 左右の余白。初期値0。
    ///   - interMargin セル間の余白。初期値0。
    ///   - aspectRatio: 横を1としたときの縦の比率。初期値1。
    init(column: Int, verticalMargin: CGFloat = 0,
         sideMargin: CGFloat = 0, interMargin: CGFloat = 0, aspectRatio: CGFloat = 1) {
        self.column = CGFloat(column)
        self.verticalMargin = verticalMargin
        self.sideMargin = sideMargin
        self.interMargin = interMargin
        self.aspectRatio = aspectRatio
    }

    /// UICollectionViewインスタンスのcollectionViewLayoutプロパティに代入する
    func collectionViewLayout() -> UICollectionViewFlowLayout {
        let layout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: verticalMargin, left: sideMargin,
                                           bottom: verticalMargin, right: sideMargin)
        layout.minimumInteritemSpacing = interMargin
        return layout
    }

    /// UICollectionViewDelegateFlowLayoutのsizeForItemAtメソッドの返却値として設定する
    func sizeForItem(parent: UICollectionView) -> CGSize {
        let totalSideMargin: CGFloat = sideMargin * 2
        let intervalCount: CGFloat = column - 1
        let totalInterMargin = interMargin * intervalCount
        let totalMargin = totalSideMargin + totalInterMargin
        let availableWidth = parent.frame.width - totalMargin
        let baseCellSize = floor(availableWidth / column)
        return CGSize(width: baseCellSize, height: baseCellSize * aspectRatio)
    }
}

呼び出し


import UIKit

final class SampleViewController: UIViewController {

    typealias Cell = SampleCollectionViewCell
    private let columnSetting = ColumnSetting(column: 3, sideMargin: 4, interMargin: 4)

    @IBOutlet private weak var collectionView: UICollectionView! {
        didSet {
            collectionView.delegate = self
            collectionView.dataSource = self
            collectionView.register(cell: Cell.self)
            collectionView.collectionViewLayout = columnSetting.collectionViewLayout()
        }
    }
}

// MARK: - UICollectionViewDelegate

extension SampleViewController: UICollectionViewDelegate {

}

// MARK: - UICollectionViewDelegateFlowLayout

extension MatchingViewController: UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize {
        return columnSetting.sizeForItem(parent: collectionView)
    }
}

// MARK: - UICollectionViewDataSource

extension SampleViewController: UICollectionViewDataSource {

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

    func collectionView(_ collectionView: UICollectionView,
                        cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseCell: Cell.self, for: indexPath)
        return cell
    }
}

参考

UICollectionViewの列数と行数を端末サイズ関係なく実装する
【Swift】sectionHeadersPinToVisibleBoundsを設定するとスクロールがカクつく不具合修正

3
0
0

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
3
0