Another Programming Blog

(mostly iOS and Ruby on Rails)

iOS: Restrict Panning of UIPageViewController to a Certain Area

Another iOS code-snippet:

I had a UIPageViewController in scrolling-mode that would allow to pan between view-controllers using a finger gesture. However, I wanted to restrict the panning area to a certain area of the screen, for example as shown in this screenshot:

Restricted Panning Area UIPageViewController

I do it by subclassing the UIPageViewController, finding its UIScrollView, and adding a new UIPanGestureRecognizer to that scrollView.

I set my subclassed UIPageViewController to be the delegate of that new UIPanGestureRegognizer. I then implement two delegate methods:

#import "LZPageViewController.h"

@interface LZPageViewController ()

@end

@implementation LZPageViewController
{
  UIPanGestureRecognizer *_scrollViewPanGestureRecognzier;
}

- (void)viewDidLoad
{
  [super viewDidLoad];
  // Do any additional setup after loading the view.
  
  for (UIView *view in self.view.subviews) {
    if ([view isKindOfClass:[UIScrollView class]])
    {
      UIScrollView *scrollView = (UIScrollView *)view;
      _scrollViewPanGestureRecognzier = [[UIPanGestureRecognizer alloc] init];
      _scrollViewPanGestureRecognzier.delegate = self;
      [scrollView addGestureRecognizer:_scrollViewPanGestureRecognzier];
    }
  }
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
  return NO;
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
  if (gestureRecognizer == _scrollViewPanGestureRecognzier)
  {
    CGPoint locationInView = [gestureRecognizer locationInView:self.view];
    if (locationInView.y > SOME_VALUE)
    {
      return YES;
    }
    return NO;
  }
  return NO;
}

In the last override I decide if I want to “eat the event” (reply YES) or if I want the original UIPanGestureViewRecognizer of the UIScrollView to handle it (reply NO). So, the YES-reply means the UIPageViewController will not scroll to the next ViewController.

P.S.: You can follow me on Twitter.

Comments

Webmentions