Swift Playgroundsで学ぶiOSプログラミング 第84回
コレクションビューをさらに使いこなす
「写真」にタッチして拡大や入れ替えを可能にするプログラム
2018年04月25日 17時00分更新
このところ、コレクションビューを利用して画像を格子状に整列させて表示したり、その画像をそれぞれ異なるサイズで表示したりする方法を取り上げてきました。今回もコレクションビューを扱います。今回は、コレクションビューを使って表示した画像にユーザーがタッチすることで、その画像に対して何らかの操作ができるようにしてみましょう。
前回までも、コレクションビューがテーブルビューに似ている点を折に触れて指摘してきました。今回のように、ユーザーの操作に対処する方法についても、やはり同じ類似性を発見することになるでしょう。具体的には、ユーザーがコレクションビューの1つのセルをタップして選択したことを検出する方法、あるいは1つのセルをドラッグして別の場所に移動しようとする操作への対応など、ほとんど共通していると言えるほど似ているのです。前回まで、コレクションビューを実際にプログラミングしてきた人なら、それも当然のことだと理解できるでしょう。
ユーザーがセルを選択した際には、例えばナビゲーション機能を利用して別のビューコントローラーに切り替え、そこで選択した画像を大きく表示したり、編集したりするという動作が考えられます。むしろかなり一般的な応答で、プログラミングもそれほど難しくなさそうです。しかし、今回はあえてそのパターンを採用せずタップされた画像をその場で他の画像より大きく表示することにします。また、ユーザーがセルをドラッグ可能にして画像の表示順をアレンジできるようにもしてみます。
ユーザーがタップして選択したセルだけをほかのセルより大きく
今回のプログラムも前回からの続きとなります。ただし今回の目的に沿うように、前回の最後の状態と比べるとむしろシンプルなものにしていきます。まず、画像を表示するセルは初期状態ではすべて同じ大きさにします。また、プレイグラウンドに追加した画像は、1回ずつのみ表示するようにします。これまではいろいろなレイアウトを試すために同じ画像を繰り返し何度も表示していました。今回は1つの画像は1回だけ表示するという、一般的な写真アプリと同様の動作とします。
まずは、復習も兼ねて、今回の出発点となるプログラムの主要な部分を見渡しながら、前回までと異なる点を説明しておきましょう。
コレクションビューを表示するコントローラーであるCollectionViewControllerの先頭では、まずselectedCellというプロパティを定義しています。このタイプはIndexPathで、ユーザーが選択したセルの位置を記憶しておくためのものです。また、前回のプログラムと同様に、サンプルとして表示する週アスの表紙画像をUIImageのオブジェクトの配列として用意しています。ただし今回も最新号の表紙画像を追加し、全部で6つの画像となりました。
このコントローラーのnumberOfItemsInSectionメソッドでは、これまでは表示したいセルの数を数値で指定していました。今回は、上で定義した表紙画像の配列の要素の数、imgs.countを返しています。また、cellForItemAtのメソッドでは、indexPath.rowを、そのまま表紙画像の配列のインデックスに設定し、そこから取り出した画像をセルにセットして返しています。
これで、あらかじめ用意した画像がそれぞれ1回ずつ表示されることになります。一方、sizeForItemAtのメソッドでは条件によって2種類のサイズを返すようにしました。ユーザーがタップして選択したセルについては400ポイント四方のサイズを返しています。それ以外は150ポイント四方です。選択されたセルかどうかは、indexPathがプロパティのselectedCellに一致しているかどうかで判断します。
そのselectedCellのプロパティの値は、同じコントローラー内のdidSelectItemAtメソッドの中で設定します。
といっても処理は非常にシンプルで、選択されたセルのインデックスパスを代入するだけです。これで、次に他のセルを選択するまでは、そのインデックスパスが記録された状態になります。つまり、そのセルは拡大表示されることになります。
selectedCellの値を変更した後は、コレクションビューの表示を更新するためにreloadData()メソッドを呼び出しています。このあたりの所作は、テーブルビューの場合とまったく同じです。
このプログラムを動作させると、6つの表紙画像が、1号1つずつ登場するコレクションビューが表示されます。
ここでどれかの画像をタップして選択してみましょう。するとその画像だけがほかよりも2倍以上に拡大されて表示されます。
コレクションビューのレイアウトもそれに合わせて変更され、1つだけを拡大しても画像同士が重なったりしないよう自動的に並び替えられます。ただ、これをしばらく動かしていると2つの点で不満を感じるかもしれません。1つは、一度タッチして拡大した画像はほかの画像にタッチするまで元に戻せないこと。つまり常にどれか1つが拡大された状態にしかならず、すべてを元のサイズに戻す方法がないのです。もう1つは、タッチして拡大した画像の表示が画面からはみ出してしまうことがある点です。もちろん手動でスクロールすれば全体を表示できますが、できれば拡大した画像は自動的に画面の中央に配置したいところです。次にそれらの不満を解消する方法を見ていきましょう。
この連載の記事
- 第100回 SceneKitの物理現象シミュレーションとアニメーションをARKitに持ち込む
- 第99回 「物理学体」と「物理学場」を設定して物理現象をシミュレーション
- 第98回 SceneKitのノードに動きを加えるプログラム
- 第97回 いろいろな形のノードをシーンの中に配置する
- 第96回 SceneKitの基礎シーンビュー、シーン、ノードを理解する
- 第95回 現実世界の床にボールや自動車のモデルを配置する
- 第94回 ARKitを使って非現実世界との融合に備える
- 第93回 ARKitが使えるiPadを識別するプログラム
- 第92回 Swift Playgrounds 2.1での問題点をまとめて解消する
- 第91回 iPadの内蔵カメラで撮影した写真を認識するプログラム
- この連載の一覧へ