0
votes

I am using a UIPageViewController to scroll through some view controllers. However, I need to dismiss the UIPageViewController at the beginning and end of the array of view controllers, ie, if while scrolling through page view controller, if we have reached the boundary of the view controller array, dismiss the view controller.

For the dismiss, I am using a UIPanGestureRecognizer called dismissPanGestureRecognizer. This works wonderfully when the transition style of UIPageViewController is UIPageViewControllerTransitionStylePageCurl. In that case I can hook up my gestures like so-

in viewDidLoad:

[pageViewController.gestureRecognizers enumerateObjectsUsingBlock:^(UIGestureRecognizer *gR, NSUInteger idx, BOOL *stop){
    gR.delegate = self;
    [dismissPanGestureRecognizer requireGestureRecognizerToFail:gR];
}];

self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;

For the UIGestureRecognizerDelegate methods, its something like this-

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    // If we are at the left boundary and this is a pan gesture going right-left,
    // return NO
    // Else If we are at the right boundary and this is a pan gesture going left-right,
    // return NO
    // Else return YES
}

So far so good. If its a pan gesture, we use it to dismiss only if page view controller gestures are not interested in it.

The problem occurs when the transition style is UIPageViewControllerTransitionStyleScroll. In that case the UIPageViewController don't have any gesture recognizers. It looks like it gets implemented using an internal view (pageViewController.view.subviews) called UIQueuingScrollView which I would rather not muck around with. What happens is that in scrolling transition type, at the boundary of the view controller, the scroll view just bounces, and the pan gesture recognizer never gets fired for dismissal. I had tried setting the bounces property of UIQueuingScrollView to NO, and then the pages don't even change.

Next I tried adding a transparent UIView on top of the UIPageViewController view and then implementing hitTest:withEvent: on that, thinking I will forward the event to pageViewController only when it is not at the boundaries. But while it does give some degree of control on when to allow pages to turn, it stops other gestures to get passed to pageController views too (like tapping on a button, etc).

I am trying to find ways on how I can get my own UIPanGestureRecognizer to get fired when I reach the boundary of a UIPageViewController (UIPageViewControllerDataSource methods returns nil), when the transition style is UIPageViewControllerTransitionStyleScroll.

I am currently testing on iOS6/iOS7.

1

1 Answers

0
votes

You might be able to achieve the desired effect by reacting to a currentPageIndex property you track on your UIPageViewController object or in the object that implements its datasource. Check this property and handle the dismissal when currentPageIndex == 0 || n-1 inside of one of the UIPageViewController delegate methods (probably the latter of the two below):

#pragma mark - UIPageViewController Delegate

- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers
{
    NSLog(@"will transition");
}

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
    NSLog(@"did finish animating");
}

Hopefully this helps...