Question

I am using a UIPageViewContoller to create a book-like page turning experience. The pages for my book are 18px narrower than the full width of the iPhone screen and are anchored on the left side of the screen. The frame for my UIPageViewController's view is then set to the frame size of these pages (width:302, height:460). I do this to give an effect that the book has multiple pages and for the page turn to look like it starts from the edge of the current visible page, just like the experience in the iBooks app.

The issue I am having is if someone tries to turn a page by panning from the far right of the screen, past the 302 px point, the pan gesture is not captured by the UIPageViewController and the page is not turned. I have watched a lot of users try to turn a page this way so I would like to fix this experience without changing the UI design.

My thinking is that I can grab the UIPanGesture from the area outside of the UIPageViewController and pass it to the UIPageViewController. I've successfully captured the pan gesture using an image view I have as the background of the whole view, but I can't figure out how to pass the gesture to the UIPageViewController to handle the page turn.

- (void) viewDidLoad {
...    

    // Add a swipe gesture recognizer to grab page flip swipes that start from the far right of the screen, past the edge of the book page
    self.panGesture = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:nil] autorelease];
    [self.panGesture setDelegate:self];
    [self.iv_background addGestureRecognizer:self.panGesture];

    //enable gesture events on the background image
    [self.iv_background setUserInteractionEnabled:YES];

...
}


#pragma mark - UIGestureRecognizer Delegates
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    // test if our control subview is on-screen
    if (self.pageController.view.superview != nil) {
       if (gestureRecognizer == self.panGesture) {
            // we touched background of the BookViewController, pass the pan to the UIPageViewController
            [self.pageController.view touchesBegan:[NSSet setWithObject:touch] withEvent:UIEventTypeTouches];

            return YES; // handle the touch
        }
    }
    return YES; // handle the touch
}
Was it helpful?

Solution

UIPageViewController has a gestureRecognizers property. The documentation seems to describe exactly what you're looking for:

gestureRecognizers

An array of UIGestureRecognizer objects that are configured to handle user interaction. (read-only)

@property(nonatomic, readonly) NSArray *gestureRecognizers

Discussion

These gesture recognizers are initially attached to a view in the page view controller’s hierarchy. To change the region of the screen in which the user can navigate using gestures, they can be placed on another view.

Availability

Available in iOS 5.0 and later. Declared In

UIPageViewController.h

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top