如何从 UIPageViewController 中的视图控制器返回上一个 VC 或下一个 VC?
Posted
技术标签:
【中文标题】如何从 UIPageViewController 中的视图控制器返回上一个 VC 或下一个 VC?【英文标题】:how to be back to previous VC or next VC from a view controller inside UIPageViewController? 【发布时间】:2019-06-13 00:25:36 【问题描述】:我有 3 个由 UIPageViewController 控制的视图控制器,如下图所示
https://i.stack.imgur.com/9Lqoj.png
如果我滑动屏幕,它会从 RedVC 移动到 BlueVC 和 YellowVC。
我想在 BlueVC 中制作下一个按钮和返回按钮。因此,如果用户按下后退按钮,它将转到 RedVC,如果用户按下下一步按钮,它将转到 YellowVC。该怎么做?
这是我在根页面视图控制器中的代码:
import UIKit
class RootPageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate
lazy var viewControllerList : [UIViewController] =
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let redVC = storyBoard.instantiateViewController(withIdentifier: "redVC")
let blueVC = storyBoard.instantiateViewController(withIdentifier: "blueVC")
let yellowVC = storyBoard.instantiateViewController(withIdentifier: "yellowVC")
return [redVC,blueVC,yellowVC]
()
// to add dot indicator
var pageControl = UIPageControl()
override func viewDidLoad()
super.viewDidLoad()
self.dataSource = self
self.delegate = self
configurePageControl()
turnIntoPage()
func turnIntoPage()
// set view controllers to be pages
if let firstViewController = viewControllerList.first
// if so then set the direction
self.setViewControllers([firstViewController], direction: .forward, animated: true, completion: nil)
// MARK: - Page View Controller Data Source functions
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController?
// a method that will handle view controller before current view controller
// make precaution , if the lodic is wrong then return nil (prevent index out of logic)
guard let vcIndex = viewControllerList.index(of: viewController) else return nil
let previousIndex = vcIndex - 1
guard previousIndex >= 0 else return nil
guard viewControllerList.count > previousIndex else return nil
// return the value
return viewControllerList[previousIndex]
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?
// a method that will handle view controller after current view controller
// make precaution , if the lodic is wrong then return nil (prevent index out of logic)
guard let vcIndex = viewControllerList.index(of: viewController) else return nil
let nextIndex = vcIndex + 1
guard viewControllerList.count != nextIndex else return nil
guard viewControllerList.count > nextIndex else return nil
// return the value
return viewControllerList[nextIndex]
// to add dot indicator
// MARK: Page View Controller Delegate functions
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool)
let pageContentViewController = pageViewController.viewControllers![0]
self.pageControl.currentPage = viewControllerList.index(of: pageContentViewController)!
func configurePageControl()
// The total number of pages that are available is based on how many available colors we have.
pageControl = UIPageControl(frame: CGRect(x: 0,y: UIScreen.main.bounds.maxY - 50,width: UIScreen.main.bounds.width,height: 50))
self.pageControl.numberOfPages = viewControllerList.count
self.pageControl.currentPage = 0
self.pageControl.tintColor = UIColor.black
self.pageControl.pageIndicatorTintColor = UIColor.white
self.pageControl.currentPageIndicatorTintColor = UIColor.black
self.view.addSubview(pageControl)
【问题讨论】:
【参考方案1】:因此,在您的RootPageViewController
中,您可以有一个使用setViewControllers
的函数。
而setViewControllers
被描述为:
// 设置可见的视图控制器,可选地带有动画。大批 应该只包括在 动画已经完成。 // 对于过渡样式 'UIPageViewControllerTransitionStylePageCurl',如果 'doubleSided' 是 'YES' 并且脊椎位置不是 'UIPageViewControllerSpineLocationMid',必须有两个视图控制器 包括在内,因为后者的视图控制器被用作背面。
所以让我们尝试创建一个Next
函数。
func next()
let vcs = self.viewControllerList
//or self.viewControllers
let currentPage = self.pageControl.currentPage
let nextPage = currentPage + 1
if nextPage < vcs.count
let nextVC = vcs[nextPage]
self.setViewControllers([nextVC], direction: .forward, animated: true) _ in
self.pageControl.currentPage = nextPage
如您所见,我们从您在代码中创建的vcs
安全地获取了一个viewController,其中包含所有页面。在我们得到下一个 viewController 之后,如果有的话,我们使用setViewControllers
。为了让它变得更好,我们设置了 pageControl
的 currentPage
来判断 pageController 底部的哪个圆圈要着色。
然后从您的BlueVC
获取您的pageController 的引用。如何?通过访问self.parent
并将其转换为您的RootPageViewController
。像这样:
@IBAction func next(_ sender: Any)
if let parentVC = self.parent as? RootPageViewController
parentVC.next()
现在,您的任务是实现previous
函数。
【讨论】:
以上是关于如何从 UIPageViewController 中的视图控制器返回上一个 VC 或下一个 VC?的主要内容,如果未能解决你的问题,请参考以下文章
如何将数据从 UIPageViewController 传递到它的“子视图”之一?
如何从 UIPageViewController 中的视图控制器返回上一个 VC 或下一个 VC?
从 UIPageViewController 中移除页面指示器
如何在 UIPageViewController 中的两个 ViewController 之间传递数据