在UIPageViewController中的不同滑动视图之间传递数据

时间:2018-10-30 01:17:52

标签: ios swift uipageviewcontroller

我正在开发一个项目,该项目具有3个可通过滑动访问的视图。

以下代码实现了我用来处理滑动动作的PageViewController:

import UIKit

class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {

    lazy var orderedViewControllers : [UIViewController] = {
        return [self.newVC(viewController : "ClimaVC"),
            self.newVC(viewController : "WeatherVC"),
            self.newVC(viewController : "ClosetVC")]
    }()

    var myViewControllers = [UIViewController]()

    var currentIndex : Int = 0


    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        self.dataSource = self

        setViewControllers([orderedViewControllers[1]],
                           direction: .forward, animated: true, completion: nil)

        self.delegate = self
    }


    func newVC(viewController : String) -> UIViewController {

        return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: viewController)
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

        guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
            return nil
        }

        let previousIndex = viewControllerIndex - 1;

        guard previousIndex >= 0 else {
            // return orderedViewControllers.last
            //Return nil to avoid swiping forever.
            return nil
        }

        guard orderedViewControllers.count > previousIndex else {
            return nil
        }

        currentIndex = previousIndex

        return orderedViewControllers[previousIndex]
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

        guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
            return nil
        }

        let nextIndex = viewControllerIndex + 1;

        guard orderedViewControllers.count != nextIndex else {
            //return orderedViewControllers.first
            //Return nil to avoid swiping forever.
            return nil
        }

        guard orderedViewControllers.count > nextIndex else {
            return nil
        }

        return orderedViewControllers[nextIndex]
    }
}

主View Controller是 WeatherVC 。在此视图中,检索时间数据并将其存储在名为 timeOfDay 的整数变量中。

根据 timeOfDay 的值,显示的背景会有所不同。虽然我可以在 WeatherVC 中使用此变量,但是我需要将此变量 timeOfDay 传递给其他两个视图控制器 ClimaVC ClosetVC

我尝试设置委托协议,但失败了,使用UIPageViewControllerDelegate提供的不同功能进行了探索,但没有找到任何帮助。

真的很感谢您的帮助,

非常感谢您!

2 个答案:

答案 0 :(得分:1)

这并不复杂,只需在pageviewcontroller数据源中分配值即可。

        import UIKit

                    class ClimaViewController: UIViewController{
            var timeOfDayClima: Int = 0

            override func viewDidAppear(_ animated: Bool) {
                super.viewDidAppear(animated)
                print (timeOfDayClima)
            }
        }

        class WeatherViewController: UIViewController{
            var timeOfDayClima: Int = 0


            override func viewDidAppear(_ animated: Bool) {
                super.viewDidAppear(animated)
               timeOfDayClima +=  1
            }
        }

        class ClosetViewController: UIViewController{
            var timeOfDayClima: Int = 0

            override func viewDidAppear(_ animated: Bool) {
                super.viewDidAppear(animated)
                print (timeOfDayClima)
            }
        }
        class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {

            lazy var orderedViewControllers : [UIViewController] = {
                return [self.newVC(viewController : "ClimaVC"),
                        self.newVC(viewController : "WeatherVC"),
                        self.newVC(viewController : "ClosetVC")]
            }()

            var myViewControllers = [UIViewController]()

            var currentIndex : Int = 0


            override func viewDidLoad() {
                super.viewDidLoad()

                // Do any additional setup after loading the view.

                self.dataSource = self

                setViewControllers([orderedViewControllers[1]],
                                   direction: .forward, animated: true, completion: nil)

                self.delegate = self


            }


            func newVC(viewController : String) -> UIViewController {

                return UIStoryboard(name: "Second", bundle: nil).instantiateViewController(withIdentifier: viewController)


            }

            func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

                //Guard = some kind of if statement.
                guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
                    return nil
                }



                let previousIndex = viewControllerIndex - 1;



                guard previousIndex >= 0 else {
                    // return orderedViewControllers.last
                    //Return nil to avoid swiping forever.
                    return nil
                }

                guard orderedViewControllers.count > previousIndex else {
                    return nil
                }

                currentIndex = previousIndex


                if(currentIndex == 0) {
                    (orderedViewControllers.first as! ClimaViewController).timeOfDayClima = (orderedViewControllers[1] as! WeatherViewController).timeOfDayClima
                }

                return orderedViewControllers[previousIndex]

            }

            func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

                //Guard = some kind of if statement.
                guard let viewControllerIndex = orderedViewControllers.index(of: viewController)
                    else {
                        return nil
                }

                let nextIndex = viewControllerIndex + 1;

                guard orderedViewControllers.count != nextIndex else {
                    //return orderedViewControllers.first
                    //Return nil to avoid swiping forever.
                    return nil
                }

                guard orderedViewControllers.count > nextIndex else {
                    return nil
                }

                currentIndex = nextIndex
                if(currentIndex == orderedViewControllers.count - 1) {
                    (orderedViewControllers.last as! ClosetViewController).timeOfDayClima = (orderedViewControllers[1] as! WeatherViewController).timeOfDayClima
                }


                if(nextIndex == 0) {
                    let secondVC = self.storyboard?.instantiateViewController(withIdentifier: "ClimaVC") as! ClimaViewController
                    secondVC.timeOfDayClima = 1
                }

                return orderedViewControllers[nextIndex]

            }

            override func didReceiveMemoryWarning() {
                super.didReceiveMemoryWarning()
                // Dispose of any resources that can be recreated.
            }


        }

答案 1 :(得分:1)

也许您也应该尝试解释设置委托协议失败的原因,因为这似乎是您正在寻找的解决方案。我在这里编写协议以供参考,但是您必须根据需要进行更改。

protocol WeatherVCDelegate {
    func changedTime(timeOfDay: Int)
}

这是棘手的部分。在WeatherVC中声明委托时,需要使用委托来调用该函数以将timeOfDay中继到其他weatherVC。这是如何工作的,任何符合委托协议的东西都会被触发使用该功能。

class WeatherVC {
    weak var delegate: WeatherVCDelegate?

func functionName() {
    delegate?.changedTime(timeOfDay: value)
}

现在,当您在PageViewController中初始化weatherVC时,您需要PageViewController符合weatherVC委托。

In PageViewController...
weatherVC.delegate = self
extension PageViewController: WeatherVCDelegate {
     ...
}

如果我的回答不够清楚,请阅读更多有关代表的内容 https://medium.com/@jamesrochabrun/implementing-delegates-in-swift-step-by-step-d3211cbac3ef