Reputation: 4747
I'd like to customize the navigation behavior of UIPageViewController
; specifically I'd like to navigate to different pages based on where on the screen the user drags her/his finger. Any pointers on where to start?
Upvotes: 0
Views: 431
Reputation: 385670
The page view controller's curl navigation is triggered by a UIPanGestureRecognizer
and UITapGestureRecognizer
. You can find these in the page view controller's gestureRecognizers
property.
In your pageViewController:viewControllerBeforeViewController:
method and your pageViewController:viewControllerAfterViewController:
method, you can ask the pan gesture recognizer for its location in the page view controller's view, and use that to decide where to navigate. You would probably want to actually delegate the decision to the currently-displayed view controller.
static UIPanGestureRecognizer *panRecognizerOfPageViewController(UIPageViewController *pageViewController) {
for (id recognizer in pageViewController.gestureRecognizers) {
if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]])
return recognizer;
}
return nil;
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerBeforeViewController:(UIViewController *)vc
{
DetailViewController *dvc = (DetailViewController *)vc;
UIPanGestureRecognizer *panner = panRecognizerOfPageViewController(pageViewController);
CGPoint point = [panner locationInView:dvc.view];
return [dvc priorViewControllerWithPoint:point];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerAfterViewController:(UIViewController *)vc
{
DetailViewController *dvc = (DetailViewController *)vc;
UIPanGestureRecognizer *panner = panRecognizerOfPageViewController(pageViewController);
CGPoint point = [panner locationInView:dvc.view];
return [dvc nextViewControllerWithPoint:point];
}
In my testing, I only have to ask the pan gesture recognizer for its location. When the gesture is a pan, both recognizers are in state “Possible”. When the gesture is a tap, the pan recognizer is in state “Failed” but it reports the location of the tap touch anyway.
Of course, this isn't documented behavior. If you don't want to rely on it, you need to get access to the current touch's location some other way. I would probably just use a subclass of UIWindow
and override its sendEvent:
to save the most recent touch event in an instance variable for easy access.
Upvotes: 1