8

The goal is to create a UIPageViewController that can only navigate forward. I am using a data source to provide the content for the UIPageViewController. The direction is set to UIPageViewControllerNavigationDirectionForward, the transition style is UIPageViewControllerTransitionStyleScroll.

The implementation of

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    // returns the next view controller
}

returns the next view controller, while the following should ensure navigating backwards is impossible

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    return nil;
}

Returning nil should indicate that navigation is not possible (as stated in the documentation). However, I am always possible to scroll back one page. Let's say I have 10 pages, I can scroll forward through all pages but at any page I can scroll back 1 page. (For example: at page 5 I can go back to page 4, at page 8 I can go back to page 7, and so on.)

I know I can avoid this by not using a data source and using the setViewControllers:direction:animated:completion: method, but I'd like to understand why my attempt is failing.

mmvie
  • 2,571
  • 7
  • 24
  • 39

2 Answers2

4

This is the behavior you get when your pageViewController has its transition style set to scroll -- I'm not sure why, but it has something to do with a scroll view being inserted into the hierarchy somewhere (which I could see being allocated if I ran my project with Instruments turned on). If the transition is Page Curl, then you don't get any previous page being displayed if your return nil where you do.

So, I think you're stuck with using setViewControllers:direction:animated:completion: unless you want to switch to the Page Curl animation.

rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • Thank you. Using PageCurl does work indeed. Searching for that resulted in finding this great answer: http://stackoverflow.com/questions/12939280/uipageviewcontroller-navigates-to-wrong-page-with-scroll-transition-style#answer-12939384 – mmvie Jan 20 '13 at 19:27
  • 1
    @mmvie, I'm not sure why Apple set it up this way -- I noticed that the first time you swipe to the left (the forward direction), viewControllerAfterViewController is called, followed by viewControllerBeforeViewController , and then viewControllerAfterViewController again if the style is set to scroll. I assume they do this to add the appropriate view controllers to the scroll view, so you can see the current one, as well as the before and after ones when you pan. – rdelmar Jan 20 '13 at 19:41
  • I noticed it as well. They are indeed ensuring that the next and previous viewControllers are always in the pageViewController's list of viewControllers. Probably to avoid any delays caused by creating the views and hence to create a good user experience. I am wondering whether this is expected behavior or not if the direction is set to forward only and when returning nil explicitly in viewControllerBeforeViewController... – mmvie Jan 21 '13 at 09:31
  • @mmvie, I don't know about "expected". It might be an unintended consequence of loading up the scroll view, but I wouldn't call it a bug. There is really no "forward only" mode -- the forward or reverse argument to setViewControllers:direction:animated:completion: just determines which animation you get if you jump to a specific page -- it doesn't have anything to do with the direction you get when swiping. – rdelmar Jan 21 '13 at 16:30
0

Here is a simple solution, simply set isLeftScrollEnabled default value to false in the protocol: UIPageViewController with configurable scroll directions

michael-martinez
  • 767
  • 6
  • 24