1
votes

I have a UIPageViewController (<UIPageViewControllerDataSource> delegate) that manages 3 UIViewController. To go from the second view to the third, i have to tap a button, otherwise the second view is the last visible page. Once on page 3, the user should be able to swipe to get back to 2, but not be able to swipe to return to 3 (the button is always necessary to get to page 3). This is part of the code:

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
    UIViewController *prevViewController = nil;
    if (viewController == self.P2ViewController) {
        prevViewController = self.P1ViewController;
    }
    if (viewController == self.P3ViewController) {
        [self pageViewController:pageViewController viewControllerAfterViewController:self.P2ViewController]; /*this doesn't work*/
        prevViewController = self.P2ViewController;
    }
    return prevViewController;
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
    UIViewController *nextViewController = nil;
    if (viewController == self.P1ViewController) {
        nextViewController = self.P2ViewController;
    }
    if (viewController == self.P2ViewController) {
        nextViewController = nil;
    }
    return nextViewController;
}

Then i have a custom UIViewController class where i have an IBAction and i pass the correct UIViewController with a static variable and a notification. Part of the code:

-(IBAction)goToPage:(NSNotification *)notification{
    /*some code*/
    [((UIPageViewController *)self.parentViewController) setViewControllers:viewControllersArray direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}

The first time i go from page 1 to 2, the second page is the last one. Then i tap the button and i go to the third page correctly with the animation (the "animated bug" in UIPageViewController works good for me). Then the third view is the last one and i can go back to the second view, but when i go back no viewControllerAfterViewController: method is called and i can still go to the third page.

Instead, i want to go back to the second page leaving the second page as the last one again, deleting the third page from the cache every time i go back. I've tried with this code in my custom UIViewController class for the second page:

-(void)viewWillAppear:(BOOL)animated{
    [((UIPageViewController *)self.parentViewController) setViewControllers:@[myStaticViewController2] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
}

but it only works the second time i try to move back or forth from that page. It's also useless calling again the viewControllerAfterViewController inside the viewControllerBeforeViewController like i did. I hope i was clear, i can't find a solution to this problem.

Thanks in advance

1
Create a small demo project and upload it, so people can try to get that to work as you wish.David H
I've created a demo project: This is the link. I hope that this hosting will workVal K.

1 Answers

3
votes

OK - think I found a way to make it work.

Put this in PageViewController, and add a declaration to the .h file:

// a button press is causing a move
- (void)moveToThirdController
{
    __weak PageViewController *pc = self;
    [self setViewControllers:@[self.P3ViewController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:^(BOOL ret)
        {
            // second dispatch may be overkill
            dispatch_async(dispatch_get_main_queue(), ^
                {
                    // it seems setting no wipes the cache
                    [pc setViewControllers:@[pc.P3ViewController] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
                } );
        } ];
}

In you second view controller, I slightly modified what you ahd there:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    __weak P2ViewController *pc = self;
    dispatch_async(dispatch_get_main_queue(), ^
        {
            [((UIPageViewController *)self.parentViewController) setViewControllers:@[pc] direction:UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
        } );
}

The key was to constantly try to get the pageViewController to remove its cache with a second call where animated is NO.

It turns out this is a variation on the solution first posted here