Search code examples
iosswiftuipageviewcontroller

Pass data in UIPageViewController between different swipe views


I am working on a project with 3 views that are accessed by swiping.

The following code implements the PageViewController I am using to handle the swiping motion:

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

The main View Controller is WeatherVC. In this view, time data is retrieved and stored in an integer variable named timeOfDay.

Depending on the value of timeOfDay, the background displayed will differ. While I was able to use this variable in WeatherVC, I need to pass this variable timeOfDay to the two other view controllers ClimaVC and ClosetVC.

I tried setting up a delegate protocol but failed, explored using the different functions provided by UIPageViewControllerDelegate and it did not get me anywhere.

I would really appreciate some help on this,

Thank you very much!


Solution

  • It's not complicated, just assign the values at the pageviewcontroller datasources.

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