【问题标题】:Pass data in UIPageViewController between different swipe views在不同的滑动视图之间传递 UIPageViewController 中的数据
【发布时间】:2019-04-03 00:11:44
【问题描述】:

我正在处理一个具有 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]
    }
}

主视图控制器是 WeatherVC。在此视图中,时间数据被检索并存储在一个名为 timeOfDay 的整数变量中。

根据timeOfDay的值,显示的背景会有所不同。虽然我能够在 WeatherVC 中使用此变量,但我需要将此变量 timeOfDay 传递给另外两个视图控制器 ClimaVC壁橱VC

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

非常感谢您对此的帮助,

非常感谢!

【问题讨论】:

    标签: ios swift uipageviewcontroller


    【解决方案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.
                }
    
    
            }
    

    【讨论】:

    • 有一些进展。 ClimaVC 接收数据但 ClosetVC 没有!我测试了收到的值,控制台返回:CLIMA TIME OF DAY = 1 CLOSET TIME OF DAY = 0。
    • 怎么回事?天气指数为 1,壁橱指数为 2,气候指数为 0
    • 刚刚再次检查了代码,我错过了currentIndex = nextIndex;。非常感谢您提供此解决方案,它工作得非常好,我希望我能够使用相同的方法来传递我的其余数据!
    【解决方案2】:

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

    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

    【讨论】:

    • 感谢您帮助我完成代理部分。到目前为止,E.Coms 的解决方案奏效了。但是,我将需要再次在我的 VC 之间传递数据,我希望您的帖子能有所帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 2014-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多