LoginSignup
26
32

More than 5 years have passed since last update.

[Swift] UIPageViewControllerのTipsまとめ (初級編)

Last updated at Posted at 2016-08-10

はじめに

久しぶりに、UIPageViewControllerを使う機会があったので、
整理しておきたいと思います。

ちなみに、UIPageViewControllerとは、
ページめくりや紙をめくるようなアニメーションができるViewControllerです。

Tips

アニメーションの種類

UIPageViewControllerTransitionStyle

定数 説明
.Scroll ページめくり
.PageCurl 紙めくり

めくる方向

UIPageViewControllerNavigationOrientation

定数 説明
.Horizontal 横方向
.Vertical 縦方向

ページを送る方向

(1) 順方向

・横方向の場合は、左にスワイプで移動
・縦方向の場合は、上にスワイプで移動

サンプルコード
extension SDTPageViewController: UIPageViewControllerDataSource {

    func pageViewController(pageViewController: UIPageViewController,
                            viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        return goFowardPage(viewController)
    }

    func pageViewController(pageViewController: UIPageViewController,
                            viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        return goBackPage(viewController)
    }

    private func goBackPage(viewController: UIViewController) -> UIViewController? {

        var index = (viewController as! SDTPageInnerViewController).pageIndex
        if index == 0 || index == NSNotFound {
            return nil
        }
        index -= 1
        return viewControllerAtIndex(index)
    }

    private func goFowardPage(viewController: UIViewController) -> UIViewController? {

        var index = (viewController as! SDTPageInnerViewController).pageIndex

        if index == NSNotFound {
            return nil;
        }
        index += 1
        if index == imageFiles.count {
            return nil;
        }
        return self.viewControllerAtIndex(index)
    }

    private func viewControllerAtIndex(index:Int) -> SDTPageInnerViewController? {

        if imageFiles.count == 0 || index >= imageFiles.count {
            return nil
        }
        if let vc = UIStoryboard.getViewController("Main", identifier: "SDTPageInnerViewController") as? SDTPageInnerViewController {
            vc.pageIndex = index
            vc.filePath = imageFiles[index]
            return vc
        }
        return nil
    }
}

(2) 逆方向

・横方向の場合は、右にスワイプで移動
・縦方向の場合は、下にスワイプで移動

順方向にめくるパターンとgoFowardPageとgoBackPageを逆にするだけです

サンプル
extension SDTPageViewController: UIPageViewControllerDataSource {

    func pageViewController(pageViewController: UIPageViewController,
                            viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        return goBackPage(viewController)
    }

    func pageViewController(pageViewController: UIPageViewController,
                            viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        return goFowardPage(viewController)
    }
}

指定ページへ移動する

スライダーと連動させたり、途中から読むなどに利用できます

サンプルコード
    func scrollToPage(pageIndex: Int) {
        if let currentViewController = viewControllerAtIndex(pageIndex) {

            if let pageViewController = pageViewController {
                pageViewController.setViewControllers([currentViewController],
                                                       direction: .Forward, animated: false, completion: nil)
            }
        }
    }

ページ番号の取得

独自のページコントローラーやページ番号の表示に利用できます

サンプルコード
extension SDTPageViewController: UIPageViewControllerDelegate {

    func pageViewController(pageViewController: UIPageViewController,
                            didFinishAnimating finished: Bool,
                                               previousViewControllers: [UIViewController],
                                               transitionCompleted completed: Bool) {

        if let vc = pageViewController.viewControllers?.first as? SDTPageInnerViewController {

            //ページ番号を表示
            print(vc.pageIndex)
        }
    }
}

オプション

おすすめは、ページ間に余白を指定できるオプションです。
該当ページを表示しているときは、余白が表示されませんが、
ページをめくるとページ間に余白ができます。

定数 説明
UIPageViewControllerOptionInterPageSpacingKey 余白を指定する

スクリーンショット 2016-08-11 0.18.42.png

サンプルコード
            pageViewController = UIPageViewController(transitionStyle: .Scroll,
                                                      navigationOrientation: .Horizontal,
                                                      options: [UIPageViewControllerOptionInterPageSpacingKey : 20])

参考ソースコード

いつも過去に作成したソースコードをコピペしているので、こちらにメモで残しておきます。
横スクロールで、順方向にページがめくれるサンプルです。
(ちなみに、StoryBoardは割愛します。ご了承ください。)

土台のViewController

SDTPageViewController.swift
import UIKit

class SDTPageViewController : UIViewController {

    private var pageViewController:UIPageViewController!
    private var imageFiles = ["image01.jpeg","image02.jpeg","image03.jpeg","image04.jpeg","image05.jpeg"]
    private var pageIndex = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        setup()
    }

    private func setup() {

        if let startingViewController = viewControllerAtIndex(0) {

            pageViewController = UIPageViewController(transitionStyle: .Scroll,
                                                      navigationOrientation: .Horizontal,
                                                      options: [UIPageViewControllerOptionInterPageSpacingKey : 20])

            if let pageViewController = pageViewController {
                pageViewController.dataSource = self
                pageViewController.delegate = self
                pageViewController.setViewControllers([startingViewController],
                                                      direction: .Forward,
                                                      animated: false,
                                                      completion: {done in})
                pageViewController.view.frame = self.view.frame
                addChildViewController(pageViewController)
                self.view.addSubview(pageViewController.view)
            }
        }
    }

    func scrollToPage(pageIndex: Int) {
        if let currentViewController = viewControllerAtIndex(pageIndex) {

            if let pageViewController = pageViewController {
                pageViewController.setViewControllers([currentViewController],
                                                       direction: .Forward, animated: false, completion: nil)
            }
        }
    }
}

extension SDTPageViewController: UIPageViewControllerDataSource {

    func pageViewController(pageViewController: UIPageViewController,
                            viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        return goFowardPage(viewController)
    }

    func pageViewController(pageViewController: UIPageViewController,
                            viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        return goBackPage(viewController)
    }

    private func goBackPage(viewController: UIViewController) -> UIViewController? {

        var index = (viewController as! SDTPageInnerViewController).pageIndex
        if index == 0 || index == NSNotFound {
            return nil
        }
        index -= 1
        return viewControllerAtIndex(index)
    }

    private func goFowardPage(viewController: UIViewController) -> UIViewController? {

        var index = (viewController as! SDTPageInnerViewController).pageIndex

        if index == NSNotFound {
            return nil;
        }
        index += 1
        if index == imageFiles.count {
            return nil;
        }
        return self.viewControllerAtIndex(index)
    }

    private func viewControllerAtIndex(index:Int) -> SDTPageInnerViewController? {

        if imageFiles.count == 0 || index >= imageFiles.count {
            return nil
        }
        if let vc = UIStoryboard.getViewController("Main", identifier: "SDTPageInnerViewController") as? SDTPageInnerViewController {
            vc.pageIndex = index
            vc.filePath = imageFiles[index]
            return vc
        }
        return nil
    }
}

extension SDTPageViewController: UIPageViewControllerDelegate {

    func pageViewController(pageViewController: UIPageViewController,
                            didFinishAnimating finished: Bool,
                                               previousViewControllers: [UIViewController],
                                               transitionCompleted completed: Bool) {

        if let vc = pageViewController.viewControllers?.first as? SDTPageInnerViewController {
            print(vc.pageIndex)
        }
    }
}

extension UIStoryboard {

    static func getViewController<T: UIViewController>(storyboardName: String, identifier: String) -> T? {
        return UIStoryboard(name: storyboardName, bundle: nil).instantiateViewControllerWithIdentifier(identifier) as? T
    }
}

ページ毎のViewController

SDTPageInnerViewController.swift
import UIKit
class SDTPageInnerViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!

    var pageIndex = 0
    var filePath = ""

    override func viewDidLoad() {
        super.viewDidLoad()
        setup()
    }

    private func setup() {
        imageView.image = UIImage(named: filePath)
    }
}

まとめ

UIPageViewControllerでよく使うTipsを纏めました。
次回は、ピンチやダブルタップで拡大・縮小する方法を纏めたいと思います。

以上です。

26
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
32