ページビューコントローラーに他のビューコントローラーをセットする
そのためには、そのものズバリのsetViewControllersというメソッドがあります。メソッド名からして複数のビューコントローラーを一度に設定するものであることを示していて、実際にビューコントローラーの配列を指定するようになっています。ところが、通常の使い方では、ここで指定するビューコントローラーは1つだけです。そのまま複数のビューコントローラーを設定すると、実行時にプログラムが落ちてしまいます。
とりあえず1つのビューコントローラーを作成し、その背景色をオレンジに設定して、setViewControllersメソッドを使ってページビューコントローラーに設定してみましょう。
当然ながら、オレンジ色のビューが表示されます。ページが1つしかないものの、これはこれで完全なページビューコントローラーということになります。
複数のページをめくって見られるようにするのがページビューコントローラーの役割ではなかったのか、と思われるでしょうが、その通りです。その複数のページは、setViewControllersメソッドで配列として指定できそうにも思えたのですが、そうではありませんでした。そうできれば楽なのですが、それだと最初にすべてのページのビューコントローラーを用意しておかなければならないことになり、非効率なばかりか、融通の効かない固定的な機能になってしまいます。
データソースを用意して前後のページをその場で指定する
とはいえ、まずはページビューコントローラーで切り替えるビューコントローラーを、あらかじめ用意しておいて、それらの間でページを切り替えられるようにしましょう。とりあえず、3つのビューコントローラーを用意して、ページの切り替えの様子を観察することにします。
まず、背景色を、それぞれオレンジ、グリーン、パープルに設定した3つのビューコントローラーを作成し、それらを配列に格納しておきます。
ページビューコントローラーは、ページを切り替える際に、データソースというオブジェクトに対して「次に表示するページのビューコントローラーをちょうだい」と要求してきます。これは、テーブルビューのコントローラーが、表示するセルの内容をそのデータソースに対して要求してくるのと同じ仕組みです。
ページビューコントローラーのデータソースになることのできるのは、UIPageViewControllerDataSourceというプロトコロルに準拠したクラスのオブジェクトです。そこで、そのクラスを記述しましょう。
ページを前後にめくれるようにするためには、最低2つのメソッドを実装する必要があります。メソッド名は長いので実際にはコードを見ていただきたいのですが、viewControllerBeforeとviewControllerAfterを名前に含む2つのメソッドです。その意味は説明不要でしょう。
もちろん、前者には今表示しているビューコントローラーの前のページを表示するビューコントローラーを返し、後者には後のページのビューコントローラーを返します。すでに3つのページのビューコントローラーは配列に記録してあるので、現在のページのビューコントローラーのインデックスを調べれば、その前のページや次のページのビューコントローラーを取り出すのは簡単です。その際、配列の最後の要素のページの後は最初のページに戻るように、逆に最初のページの前は最後のページに飛ぶようにしています。それによって、いわゆるサイクリックなページの表示が可能になります。
クラスが定義できたら、そのオブジェクトを作成し、それをページビューコントローラーのdataSourceプロパティに設定します。それだけで、ページビューコントローラーはユーザーによる操作に反応して自律的に動くようになります。
このプログラムを起動すると、最初に表示されるのはオレンジ色のページです。
最初にページビューコントローラーを作る際に、遷移のスタイルをスクロール(.scroll)に、ナビゲーションの方向を水平(.horizontal)に設定しているので、左右方向のフリック操作で、左右にスライドするようにページをめくることができます。
左方向にフリックすれば、オレンジからグリーンに、さらにグリーンからパープルにビューを切り替えていけます。
ページの数と位置を表示するインジケーター(UIPageControl)を付加する
このようにページを左右にスクロールするタイプのインターフェースでは、ページの底辺近くに複数のドットによるインジケーターを表示して、全体のページの数と、その中で今表示しているページの位置を示すのが普通でしょう。それは、ページビューコントローラーが最初から用意している機能です。そのインジケーターそのものは、正式にはページコントロール(UIPageControl)という名前のクラスとして用意されています。
これを表示するには、そのオブジェクトを作成して、ページビューコントローラーのどこかに設定すればいいのでは、と思われるでしょう。実はもっと簡単に、拍子抜けするほど少ないコードで表示可能です。
すでに見たデータソースのクラスに、さらに2つのメソッドを追加実装すれば良いのです。1つはpresentationCountで、これにはその名が示すようにページ数を返します。もう1つはpresentationIndexで、これには最初のページのインデックス(イジケーター中のドットの位置)を返すだけです。
あとはすべてページビューコントローラーが面倒を見てくれるので、インジケーターのドットの位置を移動するといった処理を記述する必要はありません。プログラムを起動して、動きを確認しておきましょう。
実際に紙のページをめくるような3Dアニメーションを表示する
ここまではUIPageViewControllerのオブジェクトを作成する際のパラメータとしてtransitionStyleには.scrollを指定していました。その結果は実際に見たように、ぴったり隣り合って配置されたページがスクロールしながら切り替わるというものでした。ちなみに、navigationOrientationに.horizontalを指定していたので左右方向のスクロールになっていましたが、そこに.verticalを指定すれば上下方向のスクロールになります。
transitionStyleとして、.scroll以外に指定可能なのは、.pageCurlです。名前から想像できるように、ページがカールしながらめくられるような3Dアニメーションをともなってビューが切り替わるというものです。
この例でははっきりわかりませんが、めくっているページの裏には、ページの表の色が透けているように見えるでしょう。これは単に色が透けているのではなく、表面に表示しているビューの内容が裏写りしているのです。ビューに文字などを表示してみれば、はっきりとわかるはずです。ページカールの表示でも、.horizontalと.verticalが選べるので、それも変更して試してみてください。
なお、pageCurlを選ぶと、それだけでページコントロールは表示されなくなります。その事実は、このページカールが、かなりページ数が多く、少なくともドットではページ位置を表現できないような用途に向いていることを暗に示しているものと考えられます。
次回の予定
今回は、タブやナビゲーションと同様に、複数のビューコントローラーを切り替える手段として、比較的歴史の新しいページビューコントローラーを、とりあえず動かしてみました。ページカールを垂直方向に設定して動かしてみている間に思いついたアプリケーションがあるので、次回はそれを具現化してみるつもりです。というわけで、次回もページビューコントローラーの続きとなりますが、ある程度実用的に使えるアプリを作る予定です。