Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What's new in UICollectionView

What's new in UICollectionView

3d0e347c8f54ae240a416ba5f0c4ba72?s=128

Masaki Haga

June 13, 2019
Tweet

More Decks by Masaki Haga

Other Decks in Programming

Transcript

  1. What’s new in UICollectionView Masaki Haga

  2. ~ iOS 12のUICollectionView - performBatchUpdate(_:completion:)を呼んでData不整合によりCrash - 親ViewControllerのViewのSizeに合わせたCellのSize指定が案外めんどくさい - 縦CollectionViewの中に横スクロールのCollectionViewを何個か入れたいが Scroll位置の保存などわりとめんどくさい

  3. 新しいUICollectionView - Data Source - Layout

  4. Apple公式のコード Using Collection View Compositional Layouts and Diffable Data Sources

  5. Data Source - [Old] UICollectionViewDataSource - reloadData() or performBatchUpdate(:_completion:) -

    UICollectionViewDiffableDataSource & NSDiffableDataSourceSnapshot - apply() - collectionViewへの差分反映はFramework側でhandleしてもらえるようになった。
  6. 古いData Sourceの宣言 - Data Source ObjectをUICollectionViewDataSourceに準拠 - collectionViewのdatasourceにData Source Objectをset

    - collectionView.reloadData()
  7. 新しいData Sourceの宣言 - UICollectionViewDiffableDataSourceをUICollectionViewとCellProviderを引数 に初期化する。(Delegate型ではなくClosure型のCallback) - State(NSDiffableDataSourceSnapshot)をapplyしてCollectionViewに反映 public typealias CellProvider

    = (UICollectionView, IndexPath, ItemIdentifierType) -> UICollectionViewCell?
  8. 注意 - Snapshotに渡すSectionの値と、Itemの値はHashable - SnapshotはHashValueによって値の同一性を認識する。 - つまり、HashableのDefaultの実装だと、propertyの変更だけで違うItemであると 認識されてしまう。

  9. こんなかんじ struct VideoCollection: Hashable { var title: String let videos:

    [Video] let identifier = UUID() func hash(into hasher: inout Hasher) { hasher.combine(identifier) } }
  10. SwiftUI - DifferenceUpdateがデフォルト - StateはHashableではなくIdentifiableに準拠する

  11. Diffアルゴリズムはどこからくるのか UICollectionViewDiffableDataSourceの実装はわからないけれども、 Swift5.1からDiff関係のAPIが増えているのでおそらくそれらを使っているのでは。 Swift Evolution: Ordered Collection Diffing

  12. New API - BidrectionalColleciton: difference(from:) - Swift Standard Library: CollectionDifference

    - Foundation: NSOrderedCollectionDifference - _CollectionChanges
  13. Layout - [Old] UICollectionViewFlowLayout + UICollectionViewDelegateFlowLayout - New APIs -

    UICollectionViewCompositionalLayout - NSCollectionLayoutSection - NSCollectionLayoutGroup - NSCollectionLayoutItem - NSCollectionLayoutSize - Section > Group > Item
  14. 古いLayoutの宣言 - UICollectionViewFlowLayout もしくはCustom UICollectionViewLayout - Delegateからサイズ情報などを返す

  15. 新しいLayoutの宣言 - UICollectionViewCompositionalLayout - initの引数として、NSCollectionLayoutSectionか、SectionProviderというClosureを渡す。 public typealias UICollectionViewCompositionalLayoutSectionProvider = (Int,

    NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? NSCollectionLayoutEnvironmentというので親CollectionViewの情報(ContentSize等)をとってくることができ る。SwiftUIでもGemetryReaderというのがあって、同じアプローチをとっているところが面白い。
  16. Nested Collection View

  17. Nested Collection View 縦スクロールの中の横スクロールが簡単に書けるようになった。 let section = NSCollectionLayoutSection(group: group) section.orthogonalScrollingBehavior

    = .continuous UIKit側で_UICollectionViewOrthogonalScrollerEmbeddedScrollView的な ScrollViewを勝手にいれてくれる。 画面外から戻ってきてももとのContentOffsetが保存されている。
  18. Reference - Advances in Collection View Layout - Advances in

    UI Data Sources