UICollectionView
https://developer.apple.com/documentation/uikit/views_and_controls/collection_views/implementing_modern_collection_views
後で読む
https://medium.com/eureka-engineering/uicollectionviewやuitableviewのreloaddataを呼ぶ必要はほとんどない-17a0635a54a9
概要
Collection View は、複数のコンテンツを特定のレイアウトで順番に列挙するのに利用でき、複数のオブジェクトのやり取りで成り立っている。
UICollectionView は、コンテンツ群の可視領域の定義 と、Layout object から取得したレイアウト情報に基づいてレイアウトを調整する 責務を持つ。DataSource object (UICollectionViewDataSource) は、表示するコンテンツ群の管理 と、コンテンツを表示する View の生成 の責務を持つ。Collection View は UITableView と同様、パフォーマンスのためにセルを再利用するため、ここで生成される View は UICollectionReusableView を継承している必要がある。Layout Object (UICollectionViewLayout) は、セルの見た目 (位置, サイズ, 色, ...) の定義 の責務を持つ。特に、UICollecitonViewLayoutAttributes は、特定のセルにどのレイアウトを適用するか?という情報を保持する。
表示される各セル自体は、これも UITableView と同様の、全体を通して NSIndexPath で一意に特定される。
https://gyazo.com/84829da9a84e00babc1171e4ebef77ce
View の再利用のライフサイクル
View がスクリーン上から消えると、削除される代わりに reuse queue に積まれる
新しいコンテンツがスクロールされて現れると、この queue から取り出される
これを活用するためには、CollecitonView に表示される view が UICollectionReusableView を継承している必要がある
Data Source オブジェクトは、CollectinoView に Cell や Supplementary View を提供する責務を持つが、直接 View を作成はしない
View から問い合わせがあった時、Data Souce は CollectionView のメソッドを利用して、適切な種類の View を deque する
https://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/CreatingCellsandViews/CreatingCellsandViews.html#//apple_ref/doc/uid/TP40012334-CH7-SW6
View が CollectionView 上のコンテンツとして表示されてから削除されるまでのライフサイクルは、大体以下のようになっていると思われる。
1. CollectionView が、UICollectionViewDataSource の collectionView(_:cellForItemAt:) に、Cell/View を問い合わせる
2. UICollectionViewDataSource は、dequeueReusableCell(withReuseIdentifier:for:) で Cell/View の取得を試みる
3-1. queue に再利用できる Cell/View がない場合
nib, Storyboard からロード、あるいは initWithFrameにより Cell/View を作成する
3-2. queue に再利用できる Cell/View がある場合
再利用対象の Cell/View について、UICollectionReusableView の prepareForReuse() が呼ばれる
再利用できるよう、Cell/View に前回の値が格納されていたら、それを削除する
上記処理が完了してから、Cell/View を返す
4. UICollectionViewDelegate の collectionView(_:willDisplay:forItemAt:) が呼ばれる
5. CollectionView 上に Cell/View が描画される
6. CollectionView 上から Cell/View が消える
7. UICollectionViewDelegate の collectionView(_:didEndDisplaying:forItemAt:) が呼ばれる
iOS9 までは、prepareForReuse や collectionView(_:cellForItemAt:) の呼び出されるタイミングがセルが画面表示される直前だったため、セルの生成に時間がかかると処理が間に合わなくなる場合があったが、呼び出されるタイミングが早くなって改善されたようだ。同様に、セルの消失の時間も少し遅くなって、その代わりにメモリ使用量が増えたとのこと。
【Swift】この時期だから見直すiOS10の新機能 UITableView UICollectionViewの改善とPre-Fetching API
表示するデータのPrefetch
UX をよくするために、UICollectionView は二種類の prefetch 機構を提供している。
Cell prefetching
例えば、新しいセルの行をグリッドレイアウトに追加する場合など、CollectionView が大量のセルを同時に要求する場合、それらのセルが表示に必要とされる時点より前にリクエストされる
デフォルトではこれ
Data prefetching
セルの要求よりも前に、CollectionViewのデータ要件の通知を受け取ることができるメカニズムを提供する
セル内のコンテンツがネットワークリクエストのような時間のかかるものである場合に便利
prefetchDataSource プロパティに UICollectionViewDataSourcePrefetching プロトコルを実装したオブジェクトを渡すと、セルのデータを prefetch した時に通知を受け取ることができる
レイアウトのライフサイクル
UICollectionView の処理のなかで、Collection View (UICollectionView) と Layout Object (UICollectionViewLayout) がやり取りをして、Collection View を描画する。
http://www.plantuml.com/plantuml/png/SoWkIImgAStDuGhrTCxFoKbDBidCpmlBJ2rNqBLJG1VpIQpCBosnKYWeIYr8B4g5SBcuR860YoG3ab54dVFpIbBpIe8pgrAjC8snqSLfZBCxI8z6UMPAIOPEHcfcUaQ99ZdEoG7JZYKbHPb9fIMfnMxvHQuvgRb0DnLxvWK1rPFch6Xq2OJ9iLmEgNafmF060000.png
UICollectionViewLayout 内で実装される主なメソッドは、下記になる。
collectionViewContentSize
CollectionView のコンテンツ全体のサイズを返す
スクロール時に利用される
prepare
View の変化によりレイアウトが invalidate になり、レイアウト更新が必要となった際時の最初に呼び出される
デフォルトでは何もしない
CollectionView のサイズやそのアイテムの位置の計算に必要な計算を行うべきタイミング
layoutAttributesForElements(in:)
CollectionView 上のある矩形範囲内の全てのアイテムおよびViewに適用すべき LayoutAttribute を返す
layoutAttributesForItem(at:)
IndexPath で示される特定のアイテムの LayoutAttribute を返す
参考
Collection View Programming Guide for iOS
UICollectionView の Layout で悩んだら - クックパッド開発者ブログ
UICollectionView Custom Layout Tutorial: Pinterest | raywenderlich.com