Kof
Kof

Reputation: 25253

UIPageViewController responds to vertical pan when orientation is set to horizontal

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?

Upvotes: 4

Views: 1641

Answers (1)

pxlshpr
pxlshpr

Reputation: 1111

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.

Upvotes: 7

Related Questions