UICollectionViewDelegate
#UICollectionView
UICollectionViewDelegate protocol は、多くのメソッドが NSIndexPath をパラメータとして受け取り、それで識別できる特定の Cell に起きたイベントを検知できるようになっている。
UICollectionView では、ある特定のセルに対して、何か特別な設定をしたり、個別にデータを注入したりしたい場合には、UICollectionViewCell をトラッキングするのではなく、この UICollectionViewDelegate 内で特定のセルに対する操作を記述する。
そもそも UICollectionView は、UICollectionDataSource にて UICollectionViewCell のインスタンスをキューに積んで使い回すので、特定のインスタンスに設定する、という方針が合わない。
以下に、どのようなメソッドがあるのか書いておく。
選択されたセルの管理
選択された時にフックして呼び出されるメソッド群。コード上からセルを選択した場合には呼び出されないので注意。
table:選択の管理
メソッド タイミング 役割
_:shouldSelectItemAtIndexPath ユーザが選択しようとした時 Item が選択できるべきか?を設定する
_:didSelectItemAtIndexPath ユーザが選択に成功した時 Item が選択されたことを伝える
_:shouldDeselectItemAtIndexPath ユーザが選択解除しようとした時 Item が選択解除できるべきか?を設定する
_:didDeselectItemAtIndexPath ユーザが選択解除に成功した時 Item が選択解除されたことを伝える
セルのハイライトの管理
table:ハイライトの管理
メソッド タイミング 役割
_:shouldHighlightItemAtIndexPath タッチイベントを処理しようとした時 ハイライトすべきか?を設定する
_:didHighlightItemAtIndexPath タッチイベントを受け取った時 Item がハイライトされたことを伝える
_:didUnhighlightItemAtIndexPath タッチが外れた時? Item があんハイライトされたことを伝える
View の追加/削除をトラッキングする
table:追加/削除のトラッキング
メソッド タイミング 役割
_:willDisplayCell:_: セルがコンテンツに追加される直前 追加を検知する
_:willDisplaySupplementaryView:_: SupplementaryViewがコンテンツに追加される直前 追加を検知する
_:didEndDisplayingCell:_: セルがColleciotnViewからコンテンツに削除される直前 削除を検知する
_:didEndDisplayingSupplementaryView:_ SupplementaryViewがコンテンツから削除される直前 削除を検知する
レイアウトの変更をハンドリングする
カスタムなレイアウト変更が行える API が生えていて、例えば以下のようなことができるようになるようだ。 
Yalantis/DisplaySwitcher
リストとグリットの表示切り替えが楽になるDisplaySwitcher
このようなレイアウト変更にフックして
collectionView(_:transitionLayoutForOldLayout:newLayout:)
カスタムな UICollectionViewTransitionLayout を返したい場合に実装する。このオブジェクトは、CollectionView のレイアウトの変更時の振る舞いをカスタマイズするのに利用できる。通常、レイアウト間の遷移は現在位置から遷移先の位置までの Item のアニメーションになる。カスタムな TransitionLayout object では、非線形なパスであったり、異なるタイミングのアルゴリズムであったり、タッチイベントの入力に応じた移動であったり、などをカスタマイズできる。
デフォルトでは、標準の UICollectionViewTransitionLayout オブジェクトを返し、それを遷移の管理に利用する。
collectionView(_:targetContentOffsetForProposedContentOffset:)
レイアウト変更時や animated な更新時に、コンテンツのオフセットをカスタマイズできる。Layout object の targetContentOffset(forProposedContentOffset:) の後に呼ばれる。コンテンツのオフセットを編集するのに、Layout object をサブクラス化したくない時に利用できる。
collectionView(_:targetIndexPathForMoveFromItemAt:toProposedIndexPath:)
ユーザが Item を移動している最中に呼び出され、ユーザが置こうとした場所 (NSIndexPath) とは別の場所に Item を配置することができる。これは、ユーザが誤って想定していない場所に Item を移動してしまうこと (あるいは、されてしまうこと) を防ぐことに利用できる。
セルに対するアクションを管理する
ここでいうアクションとは、特定のセルに対してメニューを開いて行う操作のこと。
table:アクションの管理
メソッド タイミング 役割
_:shouldShowMenuForItemAtIndexPath: Item のタップ長押し時 編集用のメニューを表示するか?を設定する
_:canPreformAction:forItemAt:withSender: 上記のメソッドの後 編集メニューからコマンドを除去する
_:performAction:forItemAtIndexPath:withSender: メニューのアクション選択時 選択されたアクションを実行する
CollecitonView 内のフォーカスを管理する
フォーカスの制御は、ここでもできるし、セル自体の canBecomeForcused メソッドでも設定できる。UIKit のフォーカスエンジンは、まずセルの canBecomeForcused を実行してから、本プロトコルの canFocusItemAtIndexPath を呼び出す。
ここで設定をしていなくても、Item が選択可能になっていれば、同時にフォーカス可能になる。
WIP
特に、tvOS のフォーカスエンジンに関して学ぶなら下記が勉強になりそう。
https://www.bignerdranch.com/blog/10-tips-for-mastering-the-focus-engine-on-tvos/
Spring-Loading を制御する
Spring-Loading を特定のセルに対して有効/無効が設定できる。
参考
https://developer.apple.com/documentation/uikit/uicollectionviewdelegate