4

I've burnt hours on this. I've initialized UIPageViewController with UIPageViewControllerNavigationOrientationHorizontal, but for some reason viewControllerBeforeViewController is called when user pans vertically.

Also, when this happens, there's no page flipping and didFinishAnimating:didFinishAnimating:previousViewControllers:transitionCompleted isn't called at all. This means that the page view controller knows this is a vertical movement..

This is the initialization code -

- (void)initPageViewController
{
    self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
                                                              navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal 
                                                                            options:nil];
    self.pageViewController.delegate = self;
    self.pageViewController.dataSource = self;

    [self addChildViewController:self.pageViewController];
    [self.view addSubview:self.pageViewController.view];

    // Set the page view controller's bounds using an inset rect so that self's view is visible around the edges of the pages.
    self.pageViewController.view.frame = self.view.bounds;

    [self.pageViewController didMoveToParentViewController:self];

    // Leave only pan recognizers enabled, so buttons positioned inside a page would work.
    for (UIGestureRecognizer *gr in self.pageViewController.gestureRecognizers)
    {
        if ([gr class] != [UIPanGestureRecognizer class])
            gr.enabled = NO;
    }
}

Any ideas?

Kof
  • 23,893
  • 9
  • 56
  • 81

1 Answers1

7

I had initially stumbled across your question facing the same problem - but I seem to have fixed it for my situation.

Basically, what I had to do was set a delegate to all the gesture recognizers attached to the UIPageViewController. So, soon after creating the UIPageViewController, I did:

for (UIGestureRecognizer *gr in self.book.gestureRecognizers)
    gr.delegate = self.book;

where book is my custom UIPageViewController (I had essentially set itself as the delegate). Finally, add this method to your UIPageViewController to restrict any vertical panning (or use the commented out line instead to restrict horizontal panning).

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
    {
        UIPanGestureRecognizer *panGestureRecognizer = (UIPanGestureRecognizer *)gestureRecognizer;
        CGPoint translation = [panGestureRecognizer translationInView:self.view];

        return fabs(translation.x) > fabs(translation.y);
//      return fabs(translation.y) > fabs(translation.x);
    }
    else
        return YES;
}

I was hinted towards this thanks to this answer - just make sure you filter out the UIPanGestureRecognizers only.

Community
  • 1
  • 1
pxlshpr
  • 986
  • 6
  • 15
  • tried this but for me the recognizer gets stuck after the first event and always returns the same translation value afterwards... – Lvsti Oct 26 '12 at 14:27
  • I have posted another possible solution in this thread: http://stackoverflow.com/questions/12533240/uipageviewcontroller-gesture-is-calling-viewcontrollerafter-but-doesnt-animate, you may check out that as well. – Lvsti Nov 07 '12 at 10:58
  • Cheers Ahmed, that solved it. Although I don't understand why isn't this done by the page view controller. – Kof Dec 15 '12 at 15:39
  • 1
    This solution caused a bounds exception when paging on the last page. That problem was solved at the this (http://stackoverflow.com/questions/12561336/in-ios6-setting-your-pageviewcontrollers-gesturerecognizers-delegate-to-a-view) post, helped me as well, so it needs to be an integral part of this solution. – Kof Dec 19 '12 at 09:46