Adding a UIPanGestureRecognizer and a UISwipeGestureRecognizer to same view causes conflicts after setting requireGestureToFail

前端 未结 2 1209
谎友^
谎友^ 2020-12-19 12:20

I added a swipe gesture recognizer and a pan gesture recognizer to the same view. These gestures should be exclusive to each other.

In order to do this I added the c

相关标签:
2条回答
  • 2020-12-19 13:10

    Late response, but I was having a similar issue where I wanted to pan to be recognized before the swipe. The only way I could get it working was to use a long press (or something similar) to set a flag to use the pan gesture as a pan or a swipe. I ended up not using swipes at all. I.e.:

    - (void) handleLongPress : (UILongPressGestureRecognizer *) gestureRecognizer
    {
        if (gestureRecognizer.state == UIGestureRecognizerStateBegan)
        {
            _canSwipe = YES;
        }
        else if (gestureRecognizer.state == UIGestureRecognizerStateEnded)
        {
            _canSwipe = NO;
        }
    }
    
    - (void) handleDragging : (id) sender
    {
        UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)sender;
        GLKVector2 dragDelta = GLKVector2Make(0., 0.);
    
        if (pan.state == UIGestureRecognizerStateBegan || pan.state == UIGestureRecognizerStateChanged)
        {
            _mousePosition = [pan translationInView:self.view];
            if (_beginDragging == NO)
            {
                _beginDragging = YES;
            }
            else
            {
                dragDelta = GLKVector2Make(_mousePosition.x - _prevMousePosition.x, _mousePosition.y - _prevMousePosition.y);
            }
    
            _prevMousePosition = _mousePosition;
        }
        else
        {
            _beginDragging = NO;
        }
    
        if (_canSwipe == YES)
        {
            if (dragDelta.x > 0)
            {
                _canSwipe = NO;
                [self.navigationController popToRootViewControllerAnimated:YES];
                NSLog(@"swipe right");
            }
            else if (dragDelta.x < 0)
            {
                _canSwipe = NO;
                [self performSegueWithIdentifier:@"toTableSegue" sender:pan];
                NSLog(@"swipe left");
            }
        }
        else
        {
            _dragDeltaTranslation = GLKVector2Make(dragDelta.x/90, dragDelta.y/90);
            _translationXY = GLKVector2Make(_translationXY.x + _dragDeltaTranslation.x, _translationXY.y - _dragDeltaTranslation.y);
        }
    }
    

    So essentially:

    1. Use long press (or some other mechanism) to activate a state of swiping (long press is nice because as soon as you release, the state goes to UIGestureRecognizerStateEnded)
    2. Then use the pan direction to determine the direction of the swipe. 2.
    0 讨论(0)
  • 2020-12-19 13:11

    According to Apple's documentation here (under Declaring a Specific Order for Two Gesture Recognizers) the way to get both UIPanGestureRecognizer and UISwipeGestureRecognizer to work on the same view is by requiring the UISwipeGesureRecognizer to fail before calling the UIPanGestureRecognizer (the opposite of what you wrote). This probably has something to do with the fact the a swipe gesture is also a pan gesture but the opposite is not necessarily true (see this SO question).

    I wrote this little piece of code and it manages to recognize both pan and swipe gestures:

    UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panned:)];
    UISwipeGestureRecognizer * swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swiped:)];
    [pan requireGestureRecognizerToFail:swipe];
    swipe.direction = (UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight);
    
    -(void)panned:(UIPanGestureRecognizer *)gesture
    {
        NSLog(@"Pan");
    }
    
    -(void)swiped:(UISwipeGestureRecognizer *)gesture
    {
        NSLog(@"Swipe");
    }
    

    This doesn't work as well as you'd hope (since you need the swipe gesture to fail there's a small delay before the pan gesture starts) but it does work. The code you posted however gives you the ability to fine tune the gestures to your liking.

    0 讨论(0)
提交回复
热议问题