🌽

モダンなUICollectionViewでシンプルなリストレイアウト その2 〜 最もシンプルなタイプ

2024/02/18に公開

では今回から実装です。まずは最もシンプルなものをモダンに作りましょう。

最もシンプルなタイプ

  • セクションネタの型 enum Section
  • セルネタの型 String

で 1セクションにすべて詰め込んだタイプです。

大まかな構成

UICollectionViewの2大情報は「レイアウト情報」と「データソース(表示する内容)」ですが、モダンCollectionViewでは、レイアウト情報はCollectionViewの中に存在し、データソースはCollectionViewの外に存在するこんな構成になります。

  • UIViewController
    • CollectionView
      • レイアウト情報
      • タップした時の処理
    • データソース

SimpleViewController

ViewController行きます。

class SimpleViewController: UIViewController {
    
    enum Section {
        case main
    }
    
    let prefectures: [String] = ["福岡", "佐賀", "長崎", "大分", "熊本", "宮崎", "鹿児島"]
 
    var dataSource: UICollectionViewDiffableDataSource<Section, String>! = nil
    var collectionView: UICollectionView! = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()
        configureHierarchy()
        configureDataSource()
    }
}

セクションネタはenumで。

configureHierarchy() がレイアウト系、configureDataSource() が(中に表示する)データ系です。

configureHierarchy()

 func configureHierarchy() {
     collectionView = UICollectionView(
          frame: view.bounds,
          collectionViewLayout: createLayout())
     collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
     view.addSubview(collectionView)
     collectionView.delegate = self //タップ操作へ対応するため
 }
func createLayout() -> UICollectionViewLayout {
    let config = UICollectionLayoutListConfiguration(appearance: .plain)
    return UICollectionViewCompositionalLayout.list(using: config)
}

レイアウト系は凝りだすと巨大化するので createLayout() として独立してます 。

configureDataSource()

//【C】リサイクル機能
let cellRegistration = UICollectionView.CellRegistration
    <UICollectionViewListCell, String> {
         (cell, indexPath, identifier) in
    var content = cell.defaultContentConfiguration()
    content.text = identifier
    cell.contentConfiguration = content
}

//データソースの作成
dataSource = UICollectionViewDiffableDataSource
    <Section, String> (collectionView: collectionView) {
    //【B】セルの内容が決定
    (collectionView: UICollectionView,
    indexPath: IndexPath,
    identifier: String) -> UICollectionViewCell? in
    return collectionView.dequeueConfiguredReusableCell(
        using: cellRegistration,
        for: indexPath,
        item: identifier)
}

//【A】構成を決める
var snapshot = NSDiffableDataSourceSnapshot<Section, String>()
snapshot.appendSections([.main])
snapshot.appendItems(prefectures, toSection: .main)
dataSource.apply(snapshot, animatingDifferences: false)

残り

昔からある didSelectItem

func collectionView(
    _ collectionView: UICollectionView,
    didSelectItemAt indexPath: IndexPath) {
    collectionView.deselectItem(at: indexPath, animated: true)
}

Discussion