iOS Swift:UIPageViewController – 以编程方式翻页

我有一个UIPageViewController,当我们向左或向右滑动页面时,它工作正常。

class ViewController: UIViewController, UIPageViewControllerDataSource { ... } 

现在我打算在页面上提供Previous / Nextbutton,这样就可以通过点击这些button来打开页面。

我如何触发滑动左/右行为或编程翻页?

注意这是SWIFT语言的问题,而不是Objective-C。

使用此function,并设置所需animation的过渡样式。

在这里输入图像说明

在这里输入图像说明

通常没有必要摆弄页面索引,什么不是。 有可能你已经在实现一个dataSource: UIPageViewControllerDataSource ,它具有你需要获得的前一个或下一个ViewController显示的所有东西。

Swift 2.2例子:

 extension UIPageViewController { func goToNextPage(){ guard let currentViewController = self.viewControllers?.first else { return } guard let nextViewController = dataSource?.pageViewController( self, viewControllerAfterViewController: currentViewController ) else { return } setViewControllers([nextViewController], direction: .Forward, animated: false, completion: nil) } func goToPreviousPage(){ guard let currentViewController = self.viewControllers?.first else { return } guard let previousViewController = dataSource?.pageViewController( self, viewControllerBeforeViewController: currentViewController ) else { return } setViewControllers([previousViewController], direction: .Reverse, animated: false, completion: nil) } } 

这样你就可以保证你正在转换的页面正是PageViewController内置的手势触发的页面。

这是一个迅速的实现:

 private func slideToPage(index: Int, completion: (() -> Void)?) { let count = //Function to get number of viewControllers if index < count { if index > currentPageIndex { if let vc = viewControllerAtIndex(index) { self.pageViewController.setViewControllers([vc], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: { (complete) -> Void in self.currentPageIndex = index completion?() }) } } else if index < currentPageIndex { if let vc = viewControllerAtIndex(index) { self.pageViewController.setViewControllers([vc], direction: UIPageViewControllerNavigationDirection.Reverse, animated: true, completion: { (complete) -> Void in self.currentPageIndex = index completion?() }) } } } } 

viewControllerAtIndex(index: Int) -> UIViewController? 是我自己的function,让正确的视图控制器刷卡。

那个答案的Swift 3版本(对animated参数做了小小的调整,因为我需要默认animation,但仍然在函数中使用参数),以防万一需要的话:

 extension UIPageViewController { func goToNextPage(animated: Bool = true) { guard let currentViewController = self.viewControllers?.first else { return } guard let nextViewController = dataSource?.pageViewController(self, viewControllerAfter: currentViewController) else { return } setViewControllers([nextViewController], direction: .forward, animated: animated, completion: nil) } func goToPreviousPage(animated: Bool = true) { guard let currentViewController = self.viewControllers?.first else { return } guard let previousViewController = dataSource?.pageViewController(self, viewControllerBefore: currentViewController) else { return } setViewControllers([previousViewController], direction: .reverse, animated: animated, completion: nil) } } 

只要把它留在这里,任何人都想用一个定义好的协议来浏览并以编程方式改变视图控制器。

 @objc protocol AppWalkThroughDelegate { @objc optional func goNextPage(forwardTo position: Int) @objc optional func goPreviousPage(fowardTo position: Int) } 

使用上面的协议,并确认根UIPageViewController来pipe理视图控制器之间的导航。

示例如下:

 class AppWalkThroughViewController: UIPageViewController, UIPageViewControllerDataSource, AppWalkThroughDelegate { // Add list of view controllers you want to load var viewControllerList : [UIViewControllers] = { let firstViewController = FirstViewController() let secondViewController = SecondViewController() // Assign root view controller as first responder secondViewController.delegate = self let thirdViewController = ThirdViewController() } override func viewDidLoad() { super.viewDidLoad() self.dataSource = self } // Navigate to next page func goNextPage(fowardTo position: Int) { let viewController = self.viewControllerList[position] setViewControllers([viewController], direction: UIPageViewControllerNavigationDirection.forward, animated: true, completion: nil) } } 

一旦完成所有这些,需要使UIPageViewController移动到下一页或上一页的子视图控制器可以使用AppWalkThroughDelegate方法,将特定的数字传递给委托属性。

下面的例子: 一旦按下button就调用委托方法

  class SecondViewController: UIViewController { var delegate: AppWalkThroughDelegate! override func viewDidLoad() { super.viewDidLoad() self.dataSource = self } @IBAction func goNextPage(_ sender: Any) { // Can be any number but not outside viewControllerList bounds delegate.goNextPage!(fowardTo: 2) } }