Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I disable the inifinite loop of ViewControllers?

I found this code online and tested it. It worked but it goes in an infinite loop. I saw some post about creating a new func for the index of the pages.

Link to the website I found the code on: http://samwize.com/2015/10/13/how-to-create-uipageviewcontroller-in-storyboard-in-container-view/

Anyone willing to edit the code so the loop ends?

import UIKit

class MyPageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

    var pages = [UIViewController]()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.delegate = self
        self.dataSource = self

        let page1: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("page1")
        let page2: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("page2")
        let page3: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("page3")

        pages.append(page1)
        pages.append(page2)
        pages.append(page3)

        setViewControllers([page2], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        let currentIndex = pages.indexOf(viewController)!
        let previousIndex = abs((currentIndex - 1) % pages.count)

        return pages[previousIndex]
    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        let currentIndex = pages.indexOf(viewController)!
        let nextIndex = abs((currentIndex + 1) % pages.count)
        return pages[nextIndex]
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
like image 399
Nathannn Avatar asked Dec 03 '22 15:12

Nathannn


2 Answers

Page view controllers are not supposed to wrap.

Your viewControllerBeforeViewController and viewControllerAfterViewController methods are both written to wrap around from the first to the last or last to first, which is wrong.

Simply rewrite viewControllerBeforeViewController to decrement currentIndex, and return that view controller unless it's <0. If it is <0, return nil.

Likewise for viewControllerAfterViewController, increment currentIndex, and if it's < pages.count, return that item, else nil.

See if you can write that code.

like image 185
Duncan C Avatar answered Dec 07 '22 23:12

Duncan C


Swift 3.0

var pages = [UIViewController]()

extension ViewController: UIPageViewControllerDataSource {
    func pageViewController(_ pageViewController: UIPageViewController,
                            viewControllerBefore viewController: UIViewController) -> UIViewController? {
        let currentIndex = pages.index(of: viewController)!
        let previousIndex = currentIndex - 1
        return (previousIndex == -1) ? nil : pages[previousIndex]
    }
    
    func pageViewController(_ pageViewController: UIPageViewController,
                            viewControllerAfter viewController: UIViewController) -> UIViewController? {
        let currentIndex = pages.index(of: viewController)!
        let nextIndex = currentIndex + 1
        return (nextIndex == pages.count) ? nil : pages[nextIndex]
    }
}
like image 31
Nik Kov Avatar answered Dec 07 '22 23:12

Nik Kov