4

I'm trying to present a PageViewController with 3 ContentViewControllers where the user can move from one page to the next but also automate the scroll to the next page with a timer.

1st Question: How do I get the Page View Controller to properly update the dots on the bottom of the page.

I've implemented three page PageViewController and have a timer based automation. The timer calls:

@objc func animation() {
    if counter < 2  {counter += 1}
    else {counter = 0}        
    self.pageViewController.setViewControllers([self.pageTutorialAtIndex(counter)], direction: UIPageViewControllerNavigationDirection.forward, animated: true, completion: nil)
}

This call to setViewControllers changes the view. However, it does not update the PageViewController dots on the bottom of the page. What needs to be done to fix that?

And obviously this class level counter does not get the currently shown ViewContoller, which leads me to my second question.

2nd Question: How do I properly implement getting the current index from the page shown? I've tried:

let current = self.pageTutorialAtIndex(0) as SplashContentViewController
var counter : Int = current.pageIndex!

thinking that this reads the current page but it seems to only read the page 0.

The class and viewDidLoad are :

class SplashViewController: UIViewController, UIPageViewControllerDataSource {

    var pageImages:NSArray!
    var pageTitles:[String]!
    var pageTexts:[String]!
    var pageViewController:UIPageViewController!
    var waitTimer : Timer!
    var counter : Int = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        pageImages = NSArray(objects:"sp_image1","sp_image2","sp_image3")
        pageTitles = [NSLocalizedString("sp_title1",comment: ""), NSLocalizedString("sp_title2", comment: ""), NSLocalizedString("sp_title3", comment: "")]
        pageTexts = [NSLocalizedString("sp_detail1",comment: ""), NSLocalizedString("sp_detail2", comment: ""), NSLocalizedString("sp_detail3", comment: "")]

        self.pageViewController = self.storyboard?.instantiateViewController(withIdentifier: "SplashPageViewController") as! UIPageViewController
        self.pageViewController.dataSource = self
        let initialContenViewController = self.pageTutorialAtIndex(0) as SplashContentViewController
        self.pageViewController.setViewControllers([initialContenViewController], direction: UIPageViewControllerNavigationDirection.forward, animated: true, completion: nil)
        self.addChildViewController(self.pageViewController)
        self.view.addSubview(self.pageViewController.view)
        self.pageViewController.didMove(toParentViewController: self)
    }

With the implement delegate methods:

func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController?
    {
        let viewController = viewController as! SplashContentViewController
        var index = viewController.pageIndex as Int
        if(index == 0 || index == NSNotFound){return nil}
        index -= 1
        return self.pageTutorialAtIndex(index)
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?
    {
        let viewController = viewController as! SplashContentViewController
        var index = viewController.pageIndex as Int
        if((index == NSNotFound)){return nil}
        index += 1
        if(index == pageImages.count){return nil}
        return self.pageTutorialAtIndex(index)
    }

    func presentationCount(for pageViewController: UIPageViewController) -> Int
    {
        return pageImages.count
    }

    func presentationIndex(for pageViewController: UIPageViewController) -> Int
    {
        return 0
    }
jscs
  • 63,694
  • 13
  • 151
  • 195
Zyntx
  • 659
  • 6
  • 19

2 Answers2

3

I seem to have found one possible answer:

1st Question: How do I get the Page View Controller to properly update the dots on the bottom of the page. Rather than return 0, returning the current counter provides the right.

 func presentationIndex(for pageViewController: UIPageViewController) -> Int
{
    return counter
}

2nd Question: How do I implement getting the current index? In my solution the counter variable identifies the current page. It doesn't properly get the index from the page shown but it works.

Implementation with the global counter variable is:

func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController?
{
    let viewController = viewController as! SplashContentViewController
    let index = viewController.pageIndex as Int

    if(index == NSNotFound){
        return nil
    }
    if(index > 0){
        counter = index - 1
        return self.pageTutorialAtIndex(counter)
    } else {
        counter = 0
        return nil
    }
}

func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?
{
    let viewController = viewController as! SplashContentViewController
    let index = viewController.pageIndex as Int
    if((index == NSNotFound)){
        return nil
    }
    if (index < pageImages.count - 1) {
        counter = index + 1
        return self.pageTutorialAtIndex(counter)
    } else {
        counter = pageImages.count - 1
        return nil
    }
}
Zyntx
  • 659
  • 6
  • 19
  • also found this very helpful https://stackoverflow.com/questions/8400870/uipageviewcontroller-return-the-current-visible-view/15687908#15687908 – Zyntx Apr 12 '18 at 19:54
0

Hi you are already setting the index of the current page in:

viewControllerBefore and viewControllerAfter

Just create a global variable and store the index value just before returning the view controller in each of those functions, something like

self.currentIndex = index 

and then return the view controller in question

return self.pageTutorialAtIndex(index)
Seif Meddeb
  • 112
  • 2
  • 9
  • Thanks for the answer but this is the same as the global 'counter' variable I'm using. I understand it is possible to get the current page without tracking it that way. – Zyntx Apr 11 '18 at 13:53