ASCII倶楽部

このページの本文へ

Swift Playgroundsで学ぶiOSプログラミング 第84回

コレクションビューをさらに使いこなす

「写真」にタッチして拡大や入れ替えを可能にするプログラム

2018年04月25日 17時00分更新

文● 柴田文彦 編集●吉田ヒロ

  • この記事をはてなブックマークに追加
  • 本文印刷

 このところ、コレクションビューを利用して画像を格子状に整列させて表示したり、その画像をそれぞれ異なるサイズで表示したりする方法を取り上げてきました。今回もコレクションビューを扱います。今回は、コレクションビューを使って表示した画像にユーザーがタッチすることで、その画像に対して何らかの操作ができるようにしてみましょう。

 前回までも、コレクションビューがテーブルビューに似ている点を折に触れて指摘してきました。今回のように、ユーザーの操作に対処する方法についても、やはり同じ類似性を発見することになるでしょう。具体的には、ユーザーがコレクションビューの1つのセルをタップして選択したことを検出する方法、あるいは1つのセルをドラッグして別の場所に移動しようとする操作への対応など、ほとんど共通していると言えるほど似ているのです。前回まで、コレクションビューを実際にプログラミングしてきた人なら、それも当然のことだと理解できるでしょう。

 ユーザーがセルを選択した際には、例えばナビゲーション機能を利用して別のビューコントローラーに切り替え、そこで選択した画像を大きく表示したり、編集したりするという動作が考えられます。むしろかなり一般的な応答で、プログラミングもそれほど難しくなさそうです。しかし、今回はあえてそのパターンを採用せずタップされた画像をその場で他の画像より大きく表示することにします。また、ユーザーがセルをドラッグ可能にして画像の表示順をアレンジできるようにもしてみます。

ユーザーがタップして選択したセルだけをほかのセルより大きく

 今回のプログラムも前回からの続きとなります。ただし今回の目的に沿うように、前回の最後の状態と比べるとむしろシンプルなものにしていきます。まず、画像を表示するセルは初期状態ではすべて同じ大きさにします。また、プレイグラウンドに追加した画像は、1回ずつのみ表示するようにします。これまではいろいろなレイアウトを試すために同じ画像を繰り返し何度も表示していました。今回は1つの画像は1回だけ表示するという、一般的な写真アプリと同様の動作とします。

 まずは、復習も兼ねて、今回の出発点となるプログラムの主要な部分を見渡しながら、前回までと異なる点を説明しておきましょう。

今回のプログラムも前回の最後のバージョンのプログラムからスタートします。CollectionViewControllerの先頭部分では、ユーザーが選択したセルを記憶するプロパティであるselectedCellを用意しています。表示するセルの数は配列として用意した画像の数に一致させます

 コレクションビューを表示するコントローラーであるCollectionViewControllerの先頭では、まずselectedCellというプロパティを定義しています。このタイプはIndexPathで、ユーザーが選択したセルの位置を記憶しておくためのものです。また、前回のプログラムと同様に、サンプルとして表示する週アスの表紙画像をUIImageのオブジェクトの配列として用意しています。ただし今回も最新号の表紙画像を追加し、全部で6つの画像となりました。

 このコントローラーのnumberOfItemsInSectionメソッドでは、これまでは表示したいセルの数を数値で指定していました。今回は、上で定義した表紙画像の配列の要素の数、imgs.countを返しています。また、cellForItemAtのメソッドでは、indexPath.rowを、そのまま表紙画像の配列のインデックスに設定し、そこから取り出した画像をセルにセットして返しています。

cellForItemAtメソッドでは、渡されたインデックスパスを画像の配列のインデックスとして、その位置に対応する画像をセットしています。セルのサイズは、選択されたものについては400ポイント四方、通常のものは150ポイント四方に設定しています

 これで、あらかじめ用意した画像がそれぞれ1回ずつ表示されることになります。一方、sizeForItemAtのメソッドでは条件によって2種類のサイズを返すようにしました。ユーザーがタップして選択したセルについては400ポイント四方のサイズを返しています。それ以外は150ポイント四方です。選択されたセルかどうかは、indexPathがプロパティのselectedCellに一致しているかどうかで判断します。

 そのselectedCellのプロパティの値は、同じコントローラー内のdidSelectItemAtメソッドの中で設定します。

ユーザーがセルとタップすると呼ばれるメソッドであるdidSelectItemAtを実装し、そのセルのインデックスパスを選択されたセルとして記憶します。その後コレクションビューをリロードすると、個々のセルのサイズを設定するメソッドが呼ばれた際に選択されたセルだけが大きくなります

 といっても処理は非常にシンプルで、選択されたセルのインデックスパスを代入するだけです。これで、次に他のセルを選択するまでは、そのインデックスパスが記録された状態になります。つまり、そのセルは拡大表示されることになります。

 selectedCellの値を変更した後は、コレクションビューの表示を更新するためにreloadData()メソッドを呼び出しています。このあたりの所作は、テーブルビューの場合とまったく同じです。

 このプログラムを動作させると、6つの表紙画像が、1号1つずつ登場するコレクションビューが表示されます。

プログラムを動かすと6号ぶんの週アスの表紙画像が整列したコレクションビューが表示されます。この中からどれかをタップして選択してみましょう

 ここでどれかの画像をタップして選択してみましょう。するとその画像だけがほかよりも2倍以上に拡大されて表示されます。

タップして選択した画像だけが大きく表示されます。ほかの画像は元のサイズのままなのでレイアウトも自動的に調整されます

 コレクションビューのレイアウトもそれに合わせて変更され、1つだけを拡大しても画像同士が重なったりしないよう自動的に並び替えられます。ただ、これをしばらく動かしていると2つの点で不満を感じるかもしれません。1つは、一度タッチして拡大した画像はほかの画像にタッチするまで元に戻せないこと。つまり常にどれか1つが拡大された状態にしかならず、すべてを元のサイズに戻す方法がないのです。もう1つは、タッチして拡大した画像の表示が画面からはみ出してしまうことがある点です。もちろん手動でスクロールすれば全体を表示できますが、できれば拡大した画像は自動的に画面の中央に配置したいところです。次にそれらの不満を解消する方法を見ていきましょう。

カテゴリートップへ

この連載の記事

週間ランキングTOP5

ASCII倶楽部会員によく見られてる記事はコレだ!

ASCII倶楽部の新着記事

会員専用動画の紹介も!