見出し画像

Lists in UICollectionViewをみた #WWDC20

こちらの記事には非公開の情報が含まれているのでApple Developer Programに登録しNDAに合意している方のみ閲覧してください

上記の記事の続きとしてListに焦点を当てたセッションを見ました。

Listを表示するためのクラス

UICollectionLayoutListConfiguration
NSCollectionLayoutSection
UICollectionViewCompositionalLayout

ListのスタイルとしてUITableViewでおなじみの.plain, .grouped, .insetGroupedがある。さらに専用のスタイルとして.sidebarと.sidebarPlainが尽かされた。これらは多カラムアプリを実装するのに利用できる。区切り線の表示・非表示、ヘッダーフッターの設定も可能。

Listを作成する方法

// Simple setup
    
let configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
let layout = UICollectionViewCompositionalLayout.list(using: configuration)

セクションごとにレイアウトをカスタマイズする方法

// 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
}

通常のヘッダーの表示方法

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
   }
}

セクションごとにヘッダーを表示するかどうかはheaderModeに.supplementaryか.noneを指定する。最初のセルをヘッダーのように見せることができる.firstItemInSectionというheaderModeもある。より詳しく知るにはAdvances in Diffable Data Sourceというセッションを観ると良い。

Presentation

UICollectionViewListCellというクラスが増えた。UITableViewより細かな設定が可能に。セパレータ、インデント、スワイプ動作、アクセサリー、コンテンツ構成について。より詳しく知るにはModern Cell Configurationセッションを参照。
Separator
Auto LayoutやDynamic Font、Safe Areaなどがある現状で正しいcontentOffsetを知るのは簡単ではない。そこでSeparator Layout Guideを導入した。

Swipe Actions

スワイプの挙動がセルの機能になった。先頭、もしくは末尾にアクションを設定できるようになった。動的な設定が必要な場合はアクションを表示しようとする直前に設定する。スワイプアクションのハンドラーではindexPathが不安定なので参照すべきではないので注意とのこと。

スワイプアクションの実装方法

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)
       completion(true)
   }
   cell.leadingSwipeActionsConfiguration = UISwipeActionsConfiguration(actions: [markFavorite])
}

Accessories

UITableViewのアクセサリーAPIはかなり限定的だった。また、UITableViewCellではアクセサリーはただの表示に過ぎなかったが、ListCellでは機能を有効にすることができる。より詳しい説明はAdvances in Diffable Data Sourceセッションを参照。ListCellのアクセサリーを設定するにはaccessoriesプロパティに設定する。

アクセサリーの設定方法

let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> { (cell, indexPath, item) in
   // @todo configure the cell's content
                                                                                           
   cell.accessories = [
       .disclosureIndicator(),
       .delete()
   ]
}

これらはUIKitが自動的に状態を処理してくれるとのこと。

まとめ

UICollectionViewでリスト表示が進化してそのうちUITableViewがUICollectionViewのリスト表示に置き換わりそうですね。サンプルコードもあるので後で試してみたいと思いました。


この記事が気に入ったらサポートをしてみませんか?