Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capture only UIView 2 finger UIPanGestureRecognizer

I have a couple of UIScrollViews in my view controller. I want to overlay a view that captures a 2 finger swipe via UIPanGestureRecognizer which will not record the UIScrollView swipe gestures.

When I put a transparent view over my content with a 2 finger pan gesture, my taps and 1 finger swipes are not detected. I tried overwriting the pointInside: method to return NO but then it doesn't record my 2 finger swipe.

The effect is similar to the 4 finger swipe to change apps.

like image 376
Andy Jacobs Avatar asked Apr 30 '13 13:04

Andy Jacobs


2 Answers

You don't need an overlay view.
First implement UIPanGestureRecognizer that will handle 2 finger pan and assign it to your view that contains UIScrollViews

UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc]
                                                initWithTarget:self 
                                                        action:@selector(handlePan:)];
panGestureRecognizer.delegate = self;
panGestureRecognizer.minimumNumberOfTouches = 2;
panGestureRecognizer.maximumNumberOfTouches = 2;
[self.view addGestureRecognizer:panGestureRecognizer];

Use UIGestureRecognizerDelegate to handle 2 finger pan with UIScrollView pan gesture

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

And finally you are able to handle 2 fingers pan

- (void)handlePan:(UIPanGestureRecognizer *)gestureRecognizer
{
    NSLog(@"pan");
}

If you want to stop scrolling UIScrollView when two finger pan is detected you can disable and enable UIScrollView pan recognizers

- (void)handlePan:(UIPanGestureRecognizer *)gestureRecognizer
{
    if(gestureRecognizer.state == UIGestureRecognizerStateBegan)
    {
        _scrollView.panGestureRecognizer.enabled = NO;
    }
    if(gestureRecognizer.state == UIGestureRecognizerStateEnded)
    {
        _scrollView.panGestureRecognizer.enabled = YES;
    }
    NSLog(@"pan");
}
like image 196
Sergey Kuryanov Avatar answered Nov 13 '22 02:11

Sergey Kuryanov


If you don't really need the overlay you can solve this with just gesture recognizers. I wrote this up as a test:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    _scrollView.contentSize = CGSizeMake(self.view.bounds.size.width * 2, self.view.bounds.size.height);

    UIView *green = [[UIView alloc] initWithFrame:self.view.bounds];
    [green setBackgroundColor:[UIColor greenColor]];

    UIView *blue = [[UIView alloc] initWithFrame:CGRectOffset(self.view.bounds, self.view.bounds.size.width, 0)];
    [blue setBackgroundColor:[UIColor blueColor]];

    [_scrollView addSubview:green];
    [_scrollView addSubview:blue];

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(twoFingerPan:)];
    [pan setMinimumNumberOfTouches:2];
    [pan setMaximumNumberOfTouches:2];
    [pan setDelaysTouchesBegan:YES];

    [_scrollView addGestureRecognizer:pan];

    [self.view addSubview:_scrollView];
}

- (void)twoFingerPan:(UIPanGestureRecognizer *)gesture {
    switch (gesture.state) {
        case UIGestureRecognizerStateBegan:
            self.scrollView.scrollEnabled = NO;
            break;
        case UIGestureRecognizerStateCancelled:
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateFailed:
            self.scrollView.scrollEnabled = YES;
            break;
        default:
            break;
    }
    NSLog(@"2 Fingers!");
}

I get the twoFingerPan: call back for when 2 fingers are used. The scroll view's panGestureRecognizer is still working at that point so I disable scrolling on the scroll view to handle the 2 finger pan. I've found this method work's pretty well. One sort of wonky thing is if the scroll view is decelerating the 2 finger gesture recognizer isn't called. Hope that helps!

like image 44
CEarwood Avatar answered Nov 13 '22 03:11

CEarwood