How can I capture which direction is being panned using UIPanGestureRecognizer?

Brandon B. picture Brandon B. · Mar 3, 2011 · Viewed 37.1k times · Source

Ok so I have been looking around at just about every option under the sun for capturing multi-touch gestures, and I have finally come full circle and am back at the UIPanGestureRecognizer.

The functionality I want is really quite simple. I have setup a two finger pan gesture, and I want to be able to shuffle through some images depending on how many pixels I move. I have all that worked out okay, but I want to be able to capture if the pan gesture is REVERSED.

Is there a built in way that I'm just not seeing to detect going back on a gesture? Would I have to store my original starting point, then track the end point, then see where they move after that and se if its less than the initial ending point and then reverse accordingly? I can see that working, but I'm hoping there is a more elegant solution!!

Thanks

EDIT:

Here is the method that the recognizer is set to fire. Its a bit of a hack, but it works:

-(void) throttle:(UIGestureRecognizer *) recognize{

throttleCounter ++;

if(throttleCounter == 6){
    throttleCounter = 0;
    [self nextPic:nil];
}

UIPanGestureRecognizer *panGesture = (UIPanGestureRecognizer *) recognize;
UIView *view = recognize.view;
if(panGesture.state == UIGestureRecognizerStateBegan){
    CGPoint translation = [panGesture translationInView:view.superview];
    NSLog(@"X: %f, Y:%f", translation.x, translation.y);
}else if(panGesture.state == UIGestureRecognizerStateEnded){
    CGPoint translation = [panGesture translationInView:view.superview];
            NSLog(@"X: %f, Y:%f", translation.x, translation.y);
}
  }

I've just gotten to the point where I am going to start trying to track the differences between values...to try and tell which way they are panning

Answer

Tommy picture Tommy · Mar 3, 2011

On UIPanGestureRecognizer you can use -velocityInView: to get the velocity of the fingers at the time that gesture was recognised.

If you wanted to do one thing on a pan right and one thing on a pan left, for example, you could do something like:

- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer
{
    CGPoint velocity = [gestureRecognizer velocityInView:yourView];

    if(velocity.x > 0)
    {
        NSLog(@"gesture went right");
    }
    else
    {
        NSLog(@"gesture went left");
    }
}

If you literally want to detect a reversal, as in you want to compare a new velocity to an old one and see if it is just in the opposite direction — whichever direction that may be — you could do:

// assuming lastGestureVelocity is a class variable...

- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer
{
    CGPoint velocity = [gestureRecognizer velocityInView:yourView];

    if(velocity.x*lastGestureVelocity.x + velocity.y*lastGestureVelocity.y > 0)
    {
        NSLog(@"gesture went in the same direction");
    }
    else
    {
        NSLog(@"gesture went in the opposite direction");
    }

    lastGestureVelocity = velocity;
}

The multiply and add thing may look a little odd. It's actually a dot product, but rest assured it'll be a positive number if the gestures are in the same direction, going down to 0 if they're exactly at right angles and then becoming a negative number if they're in the opposite direction.