iOS Swift:UIPageViewController - 以编程方式转换页面

Jas*_*per 24 uiviewcontroller ios uipageviewcontroller swift

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

class ViewController: UIViewController, UIPageViewControllerDataSource {
...
}
Run Code Online (Sandbox Code Playgroud)

现在我打算在页面上提供上一个/下一个按钮,以便通过单击这些按钮来转动页面.

如何触发向左/向右滑动或以编程方式翻页?


注意

这是Swift语言的问题,而不是Objective-C.

Sui*_*oth 49

通常没有必要摆弄页面索引,什么不是.您可能已经实现了一个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)

    }

}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以保证您正在转换的页面正是PageViewController内置手势触发的内容.

  • 我正在努力想办法如何使用你的想法更新`presentationIndexForPageViewController`.在我的`pageItemViewController`上,我有一个声明为`itemIndex`的变量.如何在此扩展程序中设置? (3认同)
  • 快速注意:此方法似乎不会触发 UIPageViewControllerDelegate(:didFinishAnimating),而在使用手势分页时确实会调用它,我怀疑这是一个错误,而不是一个功能。 (2认同)

Gli*_*gor 23

斯威夫特3的版本SuitedSloth的回答(用小的调整到animated参数,因为我需要它在默认情况下是动画,但仍进行参数的功能)的情况下,任何人都需要它:

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)
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 如果你正在更新委托中的点,你可能想要使用这个代码来完成(而不是nil):`{self in self.delegate?.pageViewController?(self,didFinishAnimating:true,previousViewControllers:[], transitionCompleted:completed)}` (2认同)

Jor*_*anC 8

使用此功能并为所需动画设置过渡样式.

在此输入图像描述

在此输入图像描述

  • @Jasper 创建一个 UIButton,当它被点击时,你会找出 UIPageViewController 中的下一个页面,并将该页面传递给 setViewControllers 方法。 (2认同)

Vas*_*sco 8

这是代表们的快速4实现.

因为我也使用UIPageViewControllerDelegate,并且没有使用大多数setViewController解决方案调用委托方法.

感谢Andrew Duncan对代表的评论.

// Functions for clicking next and previous in the navbar, Updated for swift 4
@objc func toNextArticle(){
    guard let currentViewController = self.viewControllers?.first else { return }

    guard let nextViewController = dataSource?.pageViewController( self, viewControllerAfter: currentViewController ) else { return }

    // Has to be set like this, since else the delgates for the buttons won't work
    setViewControllers([nextViewController], direction: .forward, animated: true, completion: { completed in self.delegate?.pageViewController?(self, didFinishAnimating: true, previousViewControllers: [], transitionCompleted: completed) })
}

@objc func toPreviousArticle(){
    guard let currentViewController = self.viewControllers?.first else { return }

    guard let previousViewController = dataSource?.pageViewController( self, viewControllerBefore: currentViewController ) else { return }

    // Has to be set like this, since else the delgates for the buttons won't work
    setViewControllers([previousViewController], direction: .reverse, animated: true, completion:{ completed in self.delegate?.pageViewController?(self, didFinishAnimating: true, previousViewControllers: [], transitionCompleted: completed) })
}
Run Code Online (Sandbox Code Playgroud)


Swi*_*y89 5

这是一个快速的实现:

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?()
                })
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

viewControllerAtIndex(index: Int) -> UIViewController? 是我自己的功能,用于获取正确的视图控制器以进行滑动。