Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone: setting required length of swipe gesture

I was wondering if there is an easy method to set the minimum swipe length, i.e. the length in pixel the user needs to swipe so that the gesture is recognised as a swipe.

I noticed that the normal swipe can be quite unresponsive (as compared to swiping photos in your photo library for instance).

This is the normal way, but I would like to reduce the required length of the swipe:

    - (void)viewDidLoad 
    {


    // SWIPING GESTURES:

    UISwipeGestureRecognizer *swipeLeftRecognizer;
    swipeLeftRecognizer=[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(foundLeftSwipe:)];
    swipeLeftRecognizer.direction=UISwipeGestureRecognizerDirectionLeft;
    //swipeRecognizer.numberOfTouchesRequired=1;
    [self.view addGestureRecognizer:swipeLeftRecognizer];
    [swipeLeftRecognizer release];

    UISwipeGestureRecognizer *swipeRightRecognizer;
    swipeRightRecognizer=[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(foundRightSwipe:)];
    swipeRightRecognizer.direction=UISwipeGestureRecognizerDirectionRight;
    //swipeRecognizer.numberOfTouchesRequired=1;
    [self.view addGestureRecognizer:swipeRightRecognizer];
    [swipeRightRecognizer release];


    [super viewDidLoad];
}

#pragma mark -
#pragma mark Swipes

- (void)foundLeftSwipe:(UISwipeGestureRecognizer *)recognizer {
    // do something
}

- (void)foundRightSwipe:(UISwipeGestureRecognizer *)recognizer {
    // do something
    }

I remember that there is a way to get the pixel start position and end position and then compare the two, but was just wondering if there is a simpler method, i.e. by simply defining a value for the minimum required swipe length in the code I have here.


EDIT:

This is how I recoded the whole thing:

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    gestureStartPoint = [touch locationInView:self.view];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint currentPosition = [touch locationInView:self.view];

    CGFloat deltaXX = (gestureStartPoint.x - currentPosition.x); // positive = left, negative = right
    CGFloat deltaYY = (gestureStartPoint.y - currentPosition.y); // positive = up, negative = down

    CGFloat deltaX = fabsf(gestureStartPoint.x - currentPosition.x); // will always be positive
    CGFloat deltaY = fabsf(gestureStartPoint.y - currentPosition.y); // will always be positive

    if (deltaX >= kMinimumGestureLength && deltaY <= kMaximumVariance) {
        if (deltaXX > 0) {
                label.text = @"Horizontal Left swipe detected";
                [self performSelector:@selector(eraseText) withObject:nil afterDelay:2];
            }
        else {
                label.text = @"Horizontal Right swipe detected";
                [self performSelector:@selector(eraseText) withObject:nil afterDelay:2];
            }

    }


    if (deltaY >= kMinimumGestureLength && deltaX <= kMaximumVariance) {
        if (deltaYY > 0) {
            label.text = @"Vertical up swipe detected";
            [self performSelector:@selector(eraseText) withObject:nil afterDelay:2];
            }
        else {
            label.text = @"Vertical down swipe detected";
            [self performSelector:@selector(eraseText) withObject:nil afterDelay:2];
        }


    }



}
like image 768
n.evermind Avatar asked Apr 14 '11 18:04

n.evermind


People also ask

What is touch duration on iPhone?

Use Hold Duration to determine how long you press the screen before your touch is recognized. Increasing the hold duration time beyond 0.3 seconds will cause a circular timer to display when you touch the screen. After the timer is finished, your touch will be recognized by your device as an intentional input.


1 Answers

I was facing the exact same thing, and I was looking for a solution. There is no such thing as required distance in UISwipeGestureRecognizer but that's not all you can use. I ended up using UIPanGestureRecognizer! It looks like a super class of swipe gesture recognizer and it certainly exposes more useful data.

There is a method available in this class called translationInView:(UIView *)aView the returns a CGPoint where x & y is the total distance over the whole pan gesture! something amazingly useful for our request! And it respects the direction by positive and negative values, meaning: y=+100 -> swipe up to down 100 points, x=+100 swipe left to right 100 points, etc...

What am I doing is to check if the user has panned for a given amount of points (I was looking for something like swipe down, so for me it was y>150) and then do my thing...

here is some code excerpts:

  -(void)viewDidLoad
    {
    UIPanGestureRecoginzer *panDown=[[UIPanGestureRecoginzer alloc] initWithTarget:self action:@selector(swipedDown:)];
     [self.view addGestureRecognizer:panDown];
    }
    .
    .
    .
    -(void)swipedDown:(UIPanGestureRecoginzer *)recognizer
    {
    CGPoint panned=[recognizer translationInView:self.view];
    if(panned.y>150){
    //swiped down for 150 points
        doSomething();
       }
    }

It also gives you the velocity of the pan: velocityInView:

Note: You should use your superview (self.view in most cases) if you want to have an overall pan effect.

Hope this helps: UIPanGestureRecognize Class Reference

like image 105
M. Porooshani Avatar answered Oct 24 '22 17:10

M. Porooshani