【Swift】Collection View Controllerの使い方。レイアウト変更をアニメーションさせる。(Swift 2.1、XCode 7.2)

2020年6月16日

本記事ではUICollectionViewControllerクラスのプロパティについて説明する。

Collection View Controller

 

動作確認を行うためのXcodeプロジェクトをGitHubに置いたので、試してみる人はご利用されたし。
⇒「テスト用プロジェクト

上記プロジェクトを実行すると、コレクションビューの中に10個の果物が表示され、果物をタップすると拡大画面に遷移する。画面遷移はNavigation Controllerを利用して実装している。

 

以下のコードはコレクションビューコントローラーに設定したカスタムクラス。検証はこのコードを修正しながら行う。

 

clearsSelectionOnViewWillAppearプロパティ

ビューが表示されるときにテーブルの選択を解除する(true)、または、解除しない(false)を設定するプロパティ。デフォルトはtrueになっている。

といっても、コレクションビューの初期状態は選択しても画像が変わらないので、このプロパティを変えただけでは選択が解除されたのか、されていないのかが分からない。

そこで「データを返すメソッド」を以下のコードのように変更して、セル選択時の背景画像を設定する。

 

すると以下の動画のように、選択したセルの背景色が変わる。そして遷移先画面から戻ると、選択が解除されて色が元に戻る。

 

そして、以下のコードのようにclearsSelectionOnViewWillAppearプロパティをfalseに設定して選択を解除しないようにしてみよう。

 

すると、以下の動画のように遷移先画面から戻っても選択が解除されないままになる。

installsStandardGestureForInteractiveMovementプロパティ

セルの並び替えを行うためのジェスチャーリコグナイザーをインストールする(true)、しない(false)を設定するプロパティ。trueの場合、セルを長押ししたあとにドラッグ&ドロップで移動できる。

デフォルトはtrueに設定されているのでこのまま並べ替えができるように思ってしまいそうだが、以下のメソッドをオーバーライドしないと機能しない。

検証ではメソッド内部では何もしていないが、通常は引数に渡ってくる移動元と移動先のインデックス番号を使って元データの並び替えを行う。

 

以下は実際のプレイ動画

 

useLayoutToLayoutNavigationTransitionsプロパティ

このプロパティをtrueにするとコレクションビューのレイアウトをアニメーションさせながら変更できるようになる。

利用するにはナビゲーションバーが必要で、変更後のレイアウトが定義されたコレクションビューコントローラーをナビゲーションバーにpushしてやるとアニメーションが発生する。

では、果物をタップするとアニメーションで画像が拡大されるものを実装してみよう。

メニューから「File」⇒「New」⇒「File…」を選択する。

新規ファイルを作成する。

 

テンプレートを選択する画面が表示されるので、「iOSのSource」⇒「Cocoa Touch Class」を選択する。

Cocoa Touch Classを選択する

 

クラス名を入力する画面が表示されるので、Classに「TestCollectionViewController2」、Subclass ofに「UICollectionViewController」を入力し、Nextボタンを押す。

クラス名を入力する

 

保存先を指定する画面が表示されるので、プロジェクトと同じ場所であることを確認し、Createボタンを押す。

保存先を指定する。

 

TestCollectionViewController2.swiftを以下のコードに変更する。

今回はレイアウト変更後の画面に機能は持たせないので、viewDidLoadメソッドでレイアウトの設定だけを行っている。

 

TestCollectionViewController.swiftを以下のコードに変更する。

「セル選択時の呼び出しメソッド」でuseLayoutToLayoutNavigationTransitionsプロパティをtrueにし、レイアウト変更用のコレクションビューコントローラーをナビゲーションコントローラーにpushしている。

 

以下は実際のプレイ動画

 

レイアウトを連続で変更する。

pushするのは必ず他のクラスのインスタンスにしなければならないわけではなく、自分のクラスのインスタンスをpushして再帰呼び出しのようなレイアウト変更もできる。

では、果物をクリックする度に徐々に画像が拡大していくものを実装してみよう。TestViewController.swiftを以下のコードに変更する。

どのインスタンスからも参照できる変数「レイアウト変更残回数」をクラスの外に定義し、画面幅をレイアウト変更残回数で割った値を画像の幅にする。

pushする度にレイアウト変更残回数をデクリメントすることで、レイアウトを変更する度に画像が大きくなっていく。

 

以下は実際のプレイ動画