iOS Swift:UIPageViewController - 以编程方式翻页
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30489920/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS Swift: UIPageViewController - Turning page programmatically
提问by Jasper
I have a UIPageViewController, which works fine when we swipe left or right to turn pages.
我有一个 UIPageViewController,当我们向左或向右滑动翻页时它可以正常工作。
class ViewController: UIViewController, UIPageViewControllerDataSource {
...
}
Now I intend to provide Previous/Next button on the page too, so that pages can be turned by clicking on these buttons.
现在我打算在页面上也提供上一页/下一页按钮,以便可以通过单击这些按钮来翻页。
How can I trigger the swipe left/right behaviour OR turn pages programmatically?
如何以编程方式触发向左/向右滑动行为或翻页?
Note
笔记
This is a question for Swiftlanguage, not Objective-C.
这是Swift语言的问题,而不是 Objective-C。
采纳答案by JordanC
Use this funtion and set the transition style for the animation you want.
使用此功能并为您想要的动画设置过渡样式。
回答by 0x6A75616E
There's generally no need to fiddle around with page indexes and what not. Chances are you are already implementing a dataSource: UIPageViewControllerDataSource
, which has all of what you need to get a previous or next ViewController to display.
通常不需要摆弄页面索引和什么。很有可能您已经在实现一个dataSource: UIPageViewControllerDataSource
,它具有让上一个或下一个 ViewController 显示所需的所有内容。
Swift 2.2 Example:
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)
}
}
This way you're guaranteed that the pages you're transitioning to are exactly what the PageViewController's built in gestures would trigger.
通过这种方式,您可以保证您要转换到的页面正是 PageViewController 的内置手势会触发的页面。
回答by Gligor
The Swift 3version of SuitedSloth's answer (with a small tweak to the animated
parameter as I needed it to be animated by default, but still taking a parameter in the function) in case anyone needs it:
SuitedSloth答案的Swift 3版本(对参数进行了小幅调整,因为我需要在默认情况下对其进行动画处理,但仍然在函数中使用一个参数),以防有人需要它: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)
}
}
回答by Vasco
Here is the swift 4 implementation with the delegates as well.
这也是代表的 swift 4 实现。
Since I also use the UIPageViewControllerDelegate, and the delegate methods weren't called with most of the setViewController solutions.
因为我也使用 UIPageViewControllerDelegate,并且大多数 setViewController 解决方案都没有调用委托方法。
Thanks to Andrew Duncan'sfor his comment about the delegate.
感谢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) })
}
回答by Swinny89
Here is a swift implementation of this:
这是一个快速的实现:
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?
is my own function to get the correct view controller to swipe to.
viewControllerAtIndex(index: Int) -> UIViewController?
是我自己的功能,用于获取要滑动到的正确视图控制器。
回答by Sharkes Monken
Just leaving this out here incase any one wants to use a defined protocol to navigate around and change view controllers programatically.
如果任何人想使用定义的协议来导航和以编程方式更改视图控制器,只需将其保留在这里即可。
@objc protocol AppWalkThroughDelegate {
@objc optional func goNextPage(forwardTo position: Int)
@objc optional func goPreviousPage(fowardTo position: Int)
}
Use the above protocol and confirm to root UIPageViewController to manage navigation between view controllers.
使用上面的协议并确认root UIPageViewController 来管理视图控制器之间的导航。
Example below:
下面的例子:
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)
}
}
Once achieved all that, child view controllers that need to make UIPageViewController move to next or previous page can use AppWalkThroughDelegate methods by passing a specific number onto delegate property.
一旦实现了所有这些,需要使 UIPageViewController 移动到下一页或上一页的子视图控制器可以通过将特定数字传递给委托属性来使用 AppWalkThroughDelegate 方法。
Example below: Delegate method invoked once button pressed
下面的示例:按下按钮后调用委托方法
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)
}
}