UICollectionViewにおけるリスト

Lists in UICollectionView

https://developer.apple.com/videos/play/wwdc2020/10026/

Sessionの概要

UICollectionViewを用いてリストやサイドバーを構築する方法について
Composition Layoutの柔軟性を利用しTableViewの外観を置き換ましょう。
Modular Layoutのオプションの活用やレイアウトのカスタマイズによって、アプリ内の情報をより夜いデザインで見せる方法について List ConfigurationやList Cellについて学習します。

Lists

  • Composition Layoutを用いて、UICollectionViewでUITableViewライクの表現を実現する
  • UICollectionLayoutListConfigurationでlayout設定し、NSCollectionLayoutSectionに実装する
  • Self sizingによる最適化をサポート
  • 独自のレイアウトをカスタマイズすることも可能
    • preferredLayoutAttributesFittingAttributes を使用する

List Configuration

  • UITableViewと同じStyle +αを持つ
    • .plane, .grouped, .insetGrouped
    • .sidebar, .sidebarPlain <- new
// Per section setup

let layout = UICollectionViewCompositionalLayout() {
  [weak self] sectionIndex, layoutEnvironment in
    guard let self = self else { return nil }

    // @todo: add custom layout sections for various sections

    let configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
    let section = NSCollectionLayoutSection.list(using: configuration, layoutEnvironment: layoutEnvironment)
    return section
}

Header and Footer

var configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
configuration.headerMode = .supplementary
let layout = UICollectionViewCompositionalLayout.list(using: configuration)

dataSource.supplementaryViewProvider = { (collectionView, elementKind, indexPath) in
    if elementKind == UICollectionView.elementKindSectionHeader {
        return collectionView.dequeueConfiguredReusableSupplementary(using: header, for: indexPath)
    }
    else {
        return nil
    }
}
headerを最初のItemに設定する
var configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
configuration.headerMode = .firstItemInSection
let layout = UICollectionViewCompositionalLayout.list(using: configuration)

List Cell

UICollectionViewListCell
  • Separators
    • Separator Layout Guide
  • インデント
  • スワイプアクション
  • アクセサリ
  • Defaultのコンテンツ設定

Separators

separatorのleadingをlabelのleadingに合わせるなどのAutoLayout設定が可能

スワイプアクション

スワイプアクションがList Cellの機能となる
注意点はユーザーがスワイプアクションをトリガーしたときに、
保存されたIndexPathを使用してCellのデータモデルを取得すると、対象のCellとは異なるCellのデータを操作してしまう可能性があります。
let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Model> { (cell, indexPath, item) in
    // @todo configure the cell's content

    let markFavorite = UIContextualAction(style: .normal, title: "Mark as Favorite") {
                [weak self] (_, _, completion) in
        guard let self = self else { return }
        // trigger the action with a reference to the model
        self.markItemAsFavorite(with: item.identifier) // indexPathではなく、item.identifierを設定していることに注意
        completion(true)
    }
    cell.leadingSwipeActionsConfiguration = UISwipeActionsConfiguration(actions: [markFavorite])
}

アクセサリ

削除、並び替えなどの基本的な機能のUIを提供
let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { (cell, indexPath, item) in
    // @todo configure the cell's content

    cell.accessories = [
        .disclosureIndicator(displayed: .whenNotEditing),
        .delete()
    ]
}
最新情報をチェックしよう!