ios - 如何从 UIPageViewController 内的 View Controller 返回上一个 VC 或下一个 VC?

标签 ios swift viewcontroller uipageviewcontroller

我有 3 个由 UIPageViewController 控制的 View Controller ,如下图所示

enter image description here /image/9Lqoj.png

如果我滑动屏幕,它将从 RedVC 移动到 BlueVC,再移动到 YellowVC。

我想在 BlueVC 中制作下一个按钮和后退按钮。因此,如果用户按后退按钮,它将转到 RedVC,如果用户按下一步按钮,它将转到 YellowVC。如何做到这一点?

这是我在根页面 View Controller 中的代码:

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




}

最佳答案

因此,在您的 RootPageViewController 中,您可以有一个使用 setViewControllers 的函数。

setViewControllers 的描述如下:

// Set visible view controllers, optionally with animation. Array should only include view controllers that will be visible after the animation has completed. // For transition style 'UIPageViewControllerTransitionStylePageCurl', if 'doubleSided' is 'YES' and the spine location is not 'UIPageViewControllerSpineLocationMid', two view controllers must be included, as the latter view controller is used as the back.

所以让我们尝试使用 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。为了使它更好,我们设置 pageControlcurrentPage 来告诉 pageController 底部的哪个圆圈要着色。

然后从您的 BlueVC 中获取 pageController 的引用。如何?通过访问 self.parent 并将其转换为您的 RootPageViewController。就像这样:

@IBAction func next(_ sender: Any) {
    if let parentVC = self.parent as? RootPageViewController {
        parentVC.next()
    }
}

现在,您的任务是实现先前功能。

关于ios - 如何从 UIPageViewController 内的 View Controller 返回上一个 VC 或下一个 VC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56571894/

相关文章:

ios - PresentingViewController 被设置为 nil

swift - 具有适用于 iOS 和 MacOS 目标的共享 CoreData 的 Xcode 项目

javascript - WKWebView - 防止用户文本选择触发的自动滚动

ios - 从父屏幕中删除 ViewController 保持黑色

ios - Swift:TableView 无法选择

iOS .pch 文件获取错误 : "Invalid preprocessing directive"

ios - 展开 Storyboard(退出)segue 是否可以取代父场景中对子委托(delegate)的需求?

swift - 从闭包委托(delegate)给另一个初始化器

ios - 当我允许在事件 View Controller 上进行编辑时,如何关闭 ekeventeditviewcontroller?

ios - 激活 iPhone 相机操作使我的应用程序崩溃