Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

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

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 constraint on the swipe gesture

[swipeGesture requireGestureToFail:panGesture];

(because the pan gesture should get precedence)

Problem is that the pan gesture is always invoked - even during a very fast swipe.

In order to over come this I set myself as the pan gesture's delegate. In the delegate method I set up some code as follows:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    // check if it is the relevant view
    if (gestureRecognizer.view == self.myViewWithTwoGestures)
    {
        // check that it is the pan gesture
        if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
        {
            UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
            CGPoint velocity = [pan velocityInView:gestureRecognizer.view];
            // added an arbitrary velocity for failure
            if (ABS(velocity.y) > 100)
            {
                // fail if the swipe was fast enough - this should allow the swipe gesture to be invoked
                return NO;
            }
        }
    }
    return YES;
}

Is there a suggested velocity to ensure good behavior? Is there another way to force the pan gesture to fail?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...