James Paul Mason
James Paul Mason

Reputation: 1117

UIPageViewController calling both viewControllerBeforeViewController and viewControllerAfterViewController

I've seen similar questions on stackoverflow (e.g., here, and here) but none have clear answers. I followed this tutorial but created a separate UIViewController file with it's own .xib for each page I wanted to display. On the first swipe, both viewControllerBeforeViewController and viewControllerAfterViewController get called. The tutorial uses both of these methods to increment or decrement the pageIndex. So what I end up seeing is pageIndex initialized to 0, then set to 1 when viewControllerAfterViewController is called, then immediately set to 0 when viewControllerBeforeViewController is called. Ultimately, this results in the improper display of pages.

Upvotes: 3

Views: 3137

Answers (2)

Irfan
Irfan

Reputation: 432

I think it can be simplified like bellow. There is no need for so many if/else. The point is to understand that we need to calculate new index only if it is valid i.e if it falls between 0 and number of pages:

func pageViewController(_ pageViewController: UIPageViewController,
                    viewControllerBefore viewController: UIViewController) -> UIViewController? {
    let pageContent: HomeCardVC = viewController as! HomeCardVC

    if var index = pageContent.pageIndex {
        if (index == 0 || index == NSNotFound) {
            return nil;
        }
        index = index - 1;

       return getViewControllerAtIndex(index: index)
    }
    return nil
}

func pageViewController(_ pageViewController: UIPageViewController,
                    viewControllerAfter viewController: UIViewController) ->   UIViewController? {
    let pageContent: HomeCardVC = viewController as! HomeCardVC

    if var index =  pageContent.pageIndex {
        if (index == NSNotFound || index == providersList.count - 1) {
            return nil
        }

        index = index + 1;
        return getViewControllerAtIndex(index: index)
    }
    return nil
}

Upvotes: 0

James Paul Mason
James Paul Mason

Reputation: 1117

Here's the way I got around this.

In each page view controller, I made a readonly property called index which I assigned in its implementation to be the relevant value (e.g., 1, 2, or 3). Then I did this:

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSInteger pageIndex = 0;
    if ([viewController isKindOfClass:[MainMenuPage0ViewController class]]) {
        MainMenuPage0ViewController *mainMenuPage0ViewController = (MainMenuPage0ViewController *)viewController;
        pageIndex = mainMenuPage0ViewController.index;
        pageIndex--;
    } else if ([viewController isKindOfClass:[MainMenuPage1ViewController class]]) {
        MainMenuPage1ViewController *mainMenuPage1ViewController = (MainMenuPage1ViewController *)viewController;
        pageIndex = mainMenuPage1ViewController.index;
        pageIndex--;
    } else if ([viewController isKindOfClass:[MainMenuPage2ViewController class]]) {
        MainMenuPage2ViewController *mainMenuPage2ViewController = (MainMenuPage2ViewController *)viewController;
        pageIndex = mainMenuPage2ViewController.index;
        pageIndex--;
    }

    if (pageIndex < 0) {
        return nil;
    }

    return [self viewControllerAtIndex:pageIndex];
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    NSInteger pageIndex = 0;
    if ([viewController isKindOfClass:[MainMenuPage0ViewController class]]) {
        MainMenuPage0ViewController *mainMenuPage0ViewController = (MainMenuPage0ViewController *)viewController;
        pageIndex = mainMenuPage0ViewController.index;
        pageIndex++;
    } else if ([viewController isKindOfClass:[MainMenuPage1ViewController class]]) {
        MainMenuPage1ViewController *mainMenuPage1ViewController = (MainMenuPage1ViewController *)viewController;
        pageIndex = mainMenuPage1ViewController.index;
        pageIndex++;
    } else if ([viewController isKindOfClass:[MainMenuPage2ViewController class]]) {
        MainMenuPage2ViewController *mainMenuPage2ViewController = (MainMenuPage2ViewController *)viewController;
        pageIndex = mainMenuPage2ViewController.index;
        pageIndex++;
    }

    if (pageIndex == 3) {
        return nil;
    }

    return [self viewControllerAtIndex:pageIndex];
}

Upvotes: 2

Related Questions