Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I programmatically end/reset a UIGestureRecognizer?

Say I am currently tracking a drag gesture. In my event handler I use a threshold to determine when the drag results in an action. When the threshold is crossed, I want to indicate that the drag gesture has completed.

The only thing I can find in the docs is this line here:

If you change this property to NO while a gesture recognizer is currently recognizing a gesture, the gesture recognizer transitions to a cancelled state.

So:

if (translation.y > 100) {
    // do action
    [self doAction];

    //end recognizer
    sender.enabled = NO;
    sender.enabled = YES;
}

This works but it looks like there might be a neater way.

Does anyone know of another way to indicate that a gesture has ended programmatically? I would expect something like a method -end: that generates a final event with state UIGestureRecognizerStateEnded.

like image 725
Mattijs Avatar asked Sep 05 '12 09:09

Mattijs


2 Answers

Have you defined a custom UIGestureRecognizer? If the gesture you're recognizing is different from the standard ones defined by Apple because it has a different threshold or is otherwise not the same as a regular UIPanGestureRecognizer, then it might make sense to create your own UIGestureRecognizer. (see subclassing notes)

If you have subclassed UIGestureRecognizer, you can simply set the state like this:

  self.state = UIGestureRecognizerStateEnded;

You probably want to do this in the touchesMoved:withEvent: method. Also note:

"Subclasses of UIGestureRecognizer must import UIGestureRecognizerSubclass.h. This header file contains a redeclaration of state that makes it read-write."

On the other hand, if you're only implementing a UIGestureRecognizerDelegate, the state is read-only, and there is no way to directly set it. In that case your method of disabling/enabling might be the best you can do.

like image 77
nont Avatar answered Oct 21 '22 06:10

nont


With the code you showed you need to have the logic for starting the animation when the gesture recognizer is canceled and I'd say this is not good as there are other ways that this gesture recognizer can be canceled without you wanting to have the animation done.

Considering you have a method for starting the animation you just need to call this method when the threshold is passed and when the gesture ends normally. Two different occasions then. The code you presented would look like this:

if (translation.y > 100) {
    // do action
    [self finishFlip];
    sender.enabled = NO;
    sender.enabled = YES;
}

Canceling the gesture here may be useful also if that prevents any following actions if the user keeps dragging its finger.

If you'll have a team developing over this and you need a specific event to happen you should subclass the gesture recognizer as nont suggested.

like image 30
Fábio Oliveira Avatar answered Oct 21 '22 06:10

Fábio Oliveira