【Swift】Page View Controllerの設定。画面遷移のアニメーションを変更する。(Swift 2.1、XCode 7.2)
Page View Controllerの設定
本記事ではUIPageViewController(以下、ページビューコントローラー)のアトリビュートインスペクタの設定について説明する。
以降の手順を開始する前のXcodeプロジェクトをGitHubに置いたので、試してみる人はご利用されたし。
⇒「テスト用プロジェクト」
事前準備では、ストーリーボードに4つのビューコントローラーを配置し、ページビューコントローラーを使って画面遷移できるようにしておいた。
Navigation
画面遷移するときのページの移動方向を「Horizontal(水平方向)」と「Vertical(垂直方向)」から選択する。
以下は「Vertical(垂直方向)」に設定したときのプレイ動画。画面を縦方向にドラッグしてページを移動する。
Transition Style
画面遷移するときのアニメーションの種類を「Page Curl(ページめくり)」と「Scroll(スクロール)」から選択する。
以下は「Scroll(スクロール)」に設定したときのプレイ動画。Scroll Viewを使ったような動きをビューコントローラーをまたいで行えるのが嬉しい。
Page Spacing
ページとページの余白をポイントで指定する。この設定はTransition Styleが「Scroll」のときのみ有効になる。
以下は「160」に設定したときのプレイ動画。
Spine Location
1つのビューコントローラーを本の1ページとしたときの本の背の位置を「None」、「Min」、「Mid」、「Max」から選択する。この設定はTransition Styleが「Page Curl」のときのみ有効になる。
Navigationが「Horizontal」のとき、Minは画面左端、Maxは画面右端に本の背があるようにページめくりのアニメーションが行われる。一方、Navigationが「Vertical」のときは、Minは画面上端、Maxは画面下端が本の背になる。
以下はNavigationが「Horizontal」で、Spine Locationを「Max」に設定したときのプレイ動画。
「Mid」は画面中央が本の背になる。下図のようにNavigationが「Horizontal」のときは水平方向の中央位置が本の背になる。一方、Navigationが「Vertical」のときは垂直方向の中央位置が本の背になる。
なお、「Mid」に設定したときは、Double Sidedにチェックを入れてページを両面にする必要がある。そうしなければ以下のエラーが発生する。
1画面に2つのビューコントローラーが表示されるので、以下コードの【変更箇所】のようにsetViewControllersメソッドの引数に2つのビューコントローラーを与えるように変更する必要がある。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
// // TestPageViewController.swift // import UIKit class TestPageViewController: UIPageViewController,UIPageViewControllerDataSource { let idList = ["Sea", "Morning", "Evening", "Night"] //最初からあるメソッド override func viewDidLoad() { //1ページ目のビューコントローラーを取得する。 let controller = storyboard!.instantiateViewControllerWithIdentifier(idList[0]) //【変更箇所】2ページ目のビューコントローラーを取得する。 let controller2 = storyboard!.instantiateViewControllerWithIdentifier(idList[1]) //【変更箇所】ビューコントローラーを表示する。 self.setViewControllers([controller, controller2], direction: .Forward, animated: true, completion:nil) //データ提供元に自分を設定する。 self.dataSource = self } //右ドラッグ時の呼び出しメソッド func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? { //現在のビューコントローラーのインデックス番号を取得する。 let index = idList.indexOf(viewController.restorationIdentifier!)! if (index > 0) { //前ページのビューコントローラーを返す。 return storyboard!.instantiateViewControllerWithIdentifier(idList[index-1]) } return nil } //左ドラッグ時の呼び出しメソッド func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? { //現在のビューコントローラーのインデックス番号を取得する。 let index = idList.indexOf(viewController.restorationIdentifier!)! if (index < idList.count-1) { //次ページのビューコントローラーを返す。 return storyboard!.instantiateViewControllerWithIdentifier(idList[index+1]) } return nil } //全ページ数を返すメソッド func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int { return idList.count } //初期表示のページのインデックス番号 func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int { return 0 } } |
また、ページを1回ドラッグすると「右ドラッグ時の呼び出しメソッド」または「左ドラッグ時の呼び出しメソッド」が2回連続で呼ばれるので、次の画面で表示するビューコントローラーを1つずつ返す。
これに関しては今回実装では変更無しだが、もしビューコントローラーの総数が奇数だった場合は以下のエラーが発生する。
以下はNavigationが「Horizontal」で、Spine Locationを「Mid」に設定したときのプレイ動画。画面の見易さを考慮してiPadの横画面でテストした。iPhoneの場合は縦長に縮小されて表示される。