2010-07-11 706 views
15

He configurado un UITAPGestureRecognizer en viewDidLoad de mi controlador de vista pero de alguna manera se dispara el método selector dos veces para un solo toque.UIGestureRecognizer ¿disparando dos veces?

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

Mi método:

-(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]; 
} 
+0

¿Es posible que esto suceda solo en algún momento? –

Respuesta

2

he añadido un temporizador a la vista que comprueba para asegurarse de que el contacto fue hace al menos medio segundo e ignorar el segundo toque si es demasiado pronto.

Esto es solo una solución. Me gustaría arreglar el problema real.

4

Puedo confirmar lo mismo. Envié un informe de error a Apple con un proyecto de muestra que demuestra el problema.

La solución temporal que he encontrado es desactivar el UITAPGestureRecognizer inmediatamente antes de mostrar la alerta. Luego, en los métodos de delegado de UIAlertView que implemente, vuelva a habilitarlo. Esto requiere que realice un seguimiento del GR de alguna manera, pero parece ser la solución más elegante por el momento.

Utilizando el código de ejemplo anterior:

-(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]; 
    g.enabled = NO; 
    self.activeGestureRecognizer = g; 
    [alertView show]; 
    [alertView release]; 
} 

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { 
    self.activeGestureRecognizer.enabled = YES; 
    self.activeGestureRecognizer = nil; 
} 

- (void)alertViewCancel:(UIAlertView *)alertView { 
    self.activeGestureRecognizer.enabled = YES; 
    self.activeGestureRecognizer = nil; 
} 
+0

Esta solución funcionó para mí también. ¿Es esto de hecho un error? – mvexel

+0

Tuve el mismo problema y una hoja de acción. Esta solución lo solucionó. ¡Gracias! –

+2

Este error debe resolverse a partir de iOS SDK 4.2. Pude confirmar la resolución de Apple. – gorbster

4

que tenía el mismo problema, y ​​yo notado el segundo evento tenía el estado UIGestureRecognizerStateCancelled (mientras que el primero era UIGestureRecognizerStateEnded), por lo que otra solución es ignorar el evento en Ese caso.

-1

Yo lo hice y funcionó:

primera inicializar un miembro en el objeto de manipulación que almacena el último golpe NSTimeInterval

-(id)initWithResourcePath:(NSString*)path { 

    if ([super init]) { 
     //some code 


     lastSwipe = 0; 
    } 
    return self; 

} 

A continuación, agregue este código a su método

-(void)viewDetectedRightSwipe:(UISwipeGestureRecognizer*)recognizer { 


//touch being registered  
NSTimeInterval thisTouch = [NSDate timeIntervalSinceReferenceDate]; 

//if the last swipe is the first swipe, then there's nothing to do but the handling of a correct gesture 
if(lastSwipe !=0) { 
    // find out how much time has passed between gestures 
    NSTimeInterval timeSinceLastTouch = thisTouch -lastSwipe ; 

    NSLog(@"thisTouch = %f",thisTouch); 
    NSLog(@"timeSinceLastTouch = %f",timeSinceLastTouch); 
    if (timeSinceLastTouch<0.2f) { 
     //return if this is an invalid touch 
     return; 
    } else { 
     // register the timestamp if it is valid 
     lastSwipe = thisTouch; 
     NSLog(@"left"); 
    } 

} 
// invalid gestures won't be registed because they won't get to this portion of code. 
lastSwipe = thisTouch; 
NSLog(@"left"); 
// rest of the handling code 
} 
19

Gesto los reconocedores envían acciones con diferentes estados de gestos. Entonces no es un error. Solución del problema es:

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]; 
} 
5

que estaba teniendo un doble UIAlertView surgir. Como lo mostró Nicolas Rostov arriba, esto funcionó para mí. Tanto el UIGestureRecognizerStateEnded como el UIGestureRecognizerStateRecognized estados crearon un nuevo alertView cuando se usó [alertView show] en el bloque. Con // [alertView show] comentado, ambos aparecieron en la consola, pero solo se realizó una acción.

-(void) handleTapGesture:(UIGestureRecognizer*)sender{ 
    if(sender.state != UIGestureRecognizerStateRecognized) 
    return; 
1
if(g.state != UIGestureRecognizerStateBegan) 
//instead of if(g.state != UIGestureRecognizerStateRecognized) 
return; 

Esto invocará el alertview inmediatamente después del evento de gesto. por ejemplo: si usa el evento longtap, la vista de alerta se mostrará una vez que haya quitado el dedo. Pero el estado UIGestureRecognizerStateBegan se invocará automáticamente si el gesto se reconoce automáticamente.

3

Acabo de resolver un problema similar. Resultó que tenía dos reconocimientos de gestos de toque añadidos a la vista con la misma llamada. La forma en que me enteré es mediante NSLogging el reconocedor de gestos cuando se llama al selector.

En su lugar, comprobaría para asegurarse de que no tiene dos reconocedores de gestos, uno procedente del guión gráfico y otro creado programáticamente, por ejemplo.

NSLog(@"recognizer: %@",[gestureRecognizer description]); 
+0

gran consejo. tnxx – user1105951