相変わらずUIPageViewControllerは文献がなさすぎて辛い日々を送っていますが、前回書いた記事(http://qiita.com/kentarohorie/items/f3da3339581481a3baed) の最後の方で追記した、ページ送りを数値でなく文字で行う方法についてです。
よくある記事では、UIPageViewControllerDatasourceのメソッドで以下のように、対象のコントローラにpageIndexなどのプロパティをもたせてそれを識別し、ページ送りをする実装が多いんですが、これをクラス名によって行うと処理が簡単で無駄も少なくエビバディハッピーになれます。
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
var index = (viewController as! HogeViewController).pageIndex
if index == 0 {
print("before nil:: \(index)")
return nil
}
index--
print("before's return \(index)")
return viewControllerAtIndex(index)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
var index = (viewController as! HogeViewController).pageIndex
index++
if index == self.colors.count {
print("after nil")
return nil
}
print("after's return \(index)")
return viewControllerAtIndex(index)
}
適当なコントローラを用意しましょう。
まずページ遷移の対象になるコントローラから
・HogeViewController
・PiyoViewController
・FugaViewController
これらについてはviewの背景を変えるなど適宜初期化してください。
遷移したことがわかればOKです。
また、今回は開いた最初のVCがHogeで、 [Piyo, Hoge, Fuga]の順に遷移するものとします。
次にそれらを管理するコントローラを適当に
・BoardViewController
PageViewControllerの実装
class BoardViewController: UIViewController, UIPageViewControllerDataSource {
let pageViewController = UIPageViewController(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: nil)
override func viewDidLoad() {
super.viewDidLoad()
setPageViewController()
}
//---------------pageviewcontroller---------------------
func setPageViewController() {
pageViewController.dataSource = self
let startingViewController = HogeViewController()
let viewControllers = [startingViewController]
pageViewController.setViewControllers(viewControllers, direction: .Forward, animated: false, completion: nil)
pageViewController.view.frame = self.view.frame
self.addChildViewController(pageViewController)
self.view.addSubview(pageViewController.view!)
pageViewController.didMoveToParentViewController(self)
}
//---------------pageviewcontroller Datasource---------------------
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let className = NSStringFromClass(viewController.dynamicType).componentsSeparatedByString(".").last!
if className == "HogeViewController" {
return PiyoViewController()
} else if className == "FugaViewController" {
return HogeViewController()
} else {
return nil
}
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let className = NSStringFromClass(viewController.dynamicType).componentsSeparatedByString(".").last!
if className == "HogeViewController" {
return FugaViewController()
} else if className == "PiyoViewController" {
return HogeViewController()
} else {
return nil
}
}
}
以上です!これでRunしてみてください。
重要なのは以下の記述でクラス名を取得していることと、そのクラス名によって現在のコントローラを識別、また条件を分け、適切なVCを返していることです。
pageIndexなどで行うと挙動が不安定ですが、これだと間違いなく正しく遷移してくれます。
let className = NSStringFromClass(viewController.dynamicType).componentsSeparatedByString(".").last!
あとは以下のように、このクラス名取得をUIViewControllerを拡張してメソッド化とかしてしまえば記述もすっきりです。
extension UIViewController {
func getClassName() -> String {
return NSStringFromClass(self.dynamicType).componentsSeparatedByString(".").last!
}
}