UIGestureRecognizer firing twice?

Viewed 5971

I've set up a UITapGestureRecognizer on viewDidLoad of my view controller but somehow it fires the selector method twice for a single tap.

UITapGestureRecognizer *g = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(openInMapsApp:)] autorelease];
[self.mapView addGestureRecognizer:g];

My method:

-(void)openInMapsApp:(UIGestureRecognizer*)g {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@""
                                                    message:@"This will open this location in the Maps application. Continue?"
                                                   delegate:self
                                          cancelButtonTitle:@"Cancel"
                                          otherButtonTitles:@"OK",nil];
[alertView show];
[alertView release];
}
8 Answers

Gesture recognizers send action with different gesture state. So it's not a bug. Workaround is:

 UITapGestureRecognizer *g = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(openInMapsApp:)] autorelease];
[self.mapView addGestureRecognizer:g];

-(void)openInMapsApp:(UIGestureRecognizer*)g {
if(g.state != UIGestureRecognizerStateRecognized)
    return;
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@""
                                                    message:@"This will open this location in the Maps application. Continue?"
                                                   delegate:self
                                          cancelButtonTitle:@"Cancel"
                                          otherButtonTitles:@"OK",nil];
[alertView show];
[alertView release];
}

I was having a double UIAlertView come up. As shown by Nicolas Rostov above, this worked for me. Both the UIGestureRecognizerStateEnded and the UIGestureRecognizerStateRecognized states created a new alertView when [alertView show] was used in the block. With //[alertView show] commented out, both of them still showed up on the console, but only one action took place.

-(void) handleTapGesture:(UIGestureRecognizer*)sender{
    if(sender.state != UIGestureRecognizerStateRecognized)
    return;
Related