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

ページをめくる感覚でビューコントローラーを切り替える方法

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

2018年01月09日 18時00分

ページビューコントローラーに他のビューコントローラーをセットする

 そのためには、そのものズバリのsetViewControllersというメソッドがあります。メソッド名からして複数のビューコントローラーを一度に設定するものであることを示していて、実際にビューコントローラーの配列を指定するようになっています。ところが、通常の使い方では、ここで指定するビューコントローラーは1つだけです。そのまま複数のビューコントローラーを設定すると、実行時にプログラムが落ちてしまいます。

 とりあえず1つのビューコントローラーを作成し、その背景色をオレンジに設定して、setViewControllersメソッドを使ってページビューコントローラーに設定してみましょう。

ページビューコントローラーのメソッドsetViewControllersを使って、オレンジの背景色のビューを持つビューコントローラーを設定してみました。このメソッドは、複数のビューコントローラーを配列で設定できるようになっていますが、通常は要素が1つだけの配列を指定します

 当然ながら、オレンジ色のビューが表示されます。ページが1つしかないものの、これはこれで完全なページビューコントローラーということになります。

 複数のページをめくって見られるようにするのがページビューコントローラーの役割ではなかったのか、と思われるでしょうが、その通りです。その複数のページは、setViewControllersメソッドで配列として指定できそうにも思えたのですが、そうではありませんでした。そうできれば楽なのですが、それだと最初にすべてのページのビューコントローラーを用意しておかなければならないことになり、非効率なばかりか、融通の効かない固定的な機能になってしまいます。

データソースを用意して前後のページをその場で指定する

 とはいえ、まずはページビューコントローラーで切り替えるビューコントローラーを、あらかじめ用意しておいて、それらの間でページを切り替えられるようにしましょう。とりあえず、3つのビューコントローラーを用意して、ページの切り替えの様子を観察することにします。

 まず、背景色を、それぞれオレンジ、グリーン、パープルに設定した3つのビューコントローラーを作成し、それらを配列に格納しておきます。

ページビューコントローラーを使って切り替えたい複数のビューコントローラーを用意して、配列に格納しておきます。必ずしも配列に入れる必要はないのですが、表示しているページの前後のページを取り出すには、こうしておくと都合がいいのです

 ページビューコントローラーは、ページを切り替える際に、データソースというオブジェクトに対して「次に表示するページのビューコントローラーをちょうだい」と要求してきます。これは、テーブルビューのコントローラーが、表示するセルの内容をそのデータソースに対して要求してくるのと同じ仕組みです。

 ページビューコントローラーのデータソースになることのできるのは、UIPageViewControllerDataSourceというプロトコロルに準拠したクラスのオブジェクトです。そこで、そのクラスを記述しましょう。

ページビューコントローラーの要求に応えて、現在表示しているページのビューコントローラーの前後のページのビューコントローラーを供給するためのデータソースのクラスを定義します。その中には前後のページに対応した2つのメソッドを記述します

 ページを前後にめくれるようにするためには、最低2つのメソッドを実装する必要があります。メソッド名は長いので実際にはコードを見ていただきたいのですが、viewControllerBeforeとviewControllerAfterを名前に含む2つのメソッドです。その意味は説明不要でしょう。

 もちろん、前者には今表示しているビューコントローラーの前のページを表示するビューコントローラーを返し、後者には後のページのビューコントローラーを返します。すでに3つのページのビューコントローラーは配列に記録してあるので、現在のページのビューコントローラーのインデックスを調べれば、その前のページや次のページのビューコントローラーを取り出すのは簡単です。その際、配列の最後の要素のページの後は最初のページに戻るように、逆に最初のページの前は最後のページに飛ぶようにしています。それによって、いわゆるサイクリックなページの表示が可能になります。

 クラスが定義できたら、そのオブジェクトを作成し、それをページビューコントローラーのdataSourceプロパティに設定します。それだけで、ページビューコントローラーはユーザーによる操作に反応して自律的に動くようになります。

 このプログラムを起動すると、最初に表示されるのはオレンジ色のページです。

プログラムを起動すると、最初に表示されるのは、setViewControllersメソッドで指定したオレンジの背景色のビューのページです。ここまでは前の例と変わりません

 最初にページビューコントローラーを作る際に、遷移のスタイルをスクロール(.scroll)に、ナビゲーションの方向を水平(.horizontal)に設定しているので、左右方向のフリック操作で、左右にスライドするようにページをめくることができます。

ライブビューを左右方向にフリック、またはドラッグすると、ビューは左右にスクロールしながらページが入れ替わります。もちろん、その瞬間にビューコントローラーが入れ替わっているのです

 左方向にフリックすれば、オレンジからグリーンに、さらにグリーンからパープルにビューを切り替えていけます。

3つのビューコントローラーの切り替えは、配列の最後の要素が最初の要素に、最初の要素が最後の要素につながるようにしているので、順繰りと、どちらの方向にも永久にめくっていくことができます

ページの数と位置を表示するインジケーター(UIPageControl)を付加する

 このようにページを左右にスクロールするタイプのインターフェースでは、ページの底辺近くに複数のドットによるインジケーターを表示して、全体のページの数と、その中で今表示しているページの位置を示すのが普通でしょう。それは、ページビューコントローラーが最初から用意している機能です。そのインジケーターそのものは、正式にはページコントロール(UIPageControl)という名前のクラスとして用意されています。

 これを表示するには、そのオブジェクトを作成して、ページビューコントローラーのどこかに設定すればいいのでは、と思われるでしょう。実はもっと簡単に、拍子抜けするほど少ないコードで表示可能です。

 すでに見たデータソースのクラスに、さらに2つのメソッドを追加実装すれば良いのです。1つはpresentationCountで、これにはその名が示すようにページ数を返します。もう1つはpresentationIndexで、これには最初のページのインデックス(イジケーター中のドットの位置)を返すだけです。

ページビューコントローラーのデータソースに2つのメソッド、presentationCountとpresentationIndexを追加するだけで、全ページの数と現在の位置を示すインジケーターを表示することができます

 あとはすべてページビューコントローラーが面倒を見てくれるので、インジケーターのドットの位置を移動するといった処理を記述する必要はありません。プログラムを起動して、動きを確認しておきましょう。

ビューの下辺に黒いバーが配置され、その中にドットの組み合わせによるページコントロールが表示されました。ドットの色や背景色はカスタマイズ可能です

実際に紙のページをめくるような3Dアニメーションを表示する

 ここまではUIPageViewControllerのオブジェクトを作成する際のパラメータとしてtransitionStyleには.scrollを指定していました。その結果は実際に見たように、ぴったり隣り合って配置されたページがスクロールしながら切り替わるというものでした。ちなみに、navigationOrientationに.horizontalを指定していたので左右方向のスクロールになっていましたが、そこに.verticalを指定すれば上下方向のスクロールになります。

 transitionStyleとして、.scroll以外に指定可能なのは、.pageCurlです。名前から想像できるように、ページがカールしながらめくられるような3Dアニメーションをともなってビューが切り替わるというものです。

ページビューコントローラーのオブジェクトを作成する際のtransitionStyleのパラメータとして.pageCurlを指定するだけで、紙のページをカールさせながらめくるような3Dアニメーションが表示されるようになります

 この例でははっきりわかりませんが、めくっているページの裏には、ページの表の色が透けているように見えるでしょう。これは単に色が透けているのではなく、表面に表示しているビューの内容が裏写りしているのです。ビューに文字などを表示してみれば、はっきりとわかるはずです。ページカールの表示でも、.horizontalと.verticalが選べるので、それも変更して試してみてください。

 なお、pageCurlを選ぶと、それだけでページコントロールは表示されなくなります。その事実は、このページカールが、かなりページ数が多く、少なくともドットではページ位置を表現できないような用途に向いていることを暗に示しているものと考えられます。

次回の予定

 今回は、タブやナビゲーションと同様に、複数のビューコントローラーを切り替える手段として、比較的歴史の新しいページビューコントローラーを、とりあえず動かしてみました。ページカールを垂直方向に設定して動かしてみている間に思いついたアプリケーションがあるので、次回はそれを具現化してみるつもりです。というわけで、次回もページビューコントローラーの続きとなりますが、ある程度実用的に使えるアプリを作る予定です。

mobileASCII.jp TOPページへ

mobile ASCII

Access Rankingアクセスランキング