2010-07-11 5 views
15

J'ai mis en place un UITapGestureRecognizer sur viewDidLoad de mon contrôleur de vue, mais de toute façon il déclenche la méthode de sélection deux fois pour un seul clic.UIGestureRecognizer tirant deux fois?

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

Ma méthode:

-(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

Est-il possible que cela se produise seulement un jour? –

Répondre

2

J'ai ajouté une minuterie à la vue qui vérifie que le toucher était au moins une demi-seconde et il y a ignorer la seconde touche si elle est trop tôt.

Ceci est seulement une solution de contournement. Je voudrais toujours résoudre le vrai problème.

4

Je peux confirmer la même chose. J'ai soumis un rapport de bogue à Apple avec un exemple de projet démontrant le problème.

La solution de contournement temporaire que j'ai trouvée consiste à désactiver UITapGestureRecognizer immédiatement avant d'afficher l'alerte. Ensuite, dans la ou les méthodes déléguées UIAlertView que vous implémentez, réactivez-la. Cela vous oblige à garder une trace de la GR en quelque sorte, mais il semble que la solution la plus élégante pour le moment.

En utilisant l'exemple de code ci-dessus:

-(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

Cette solution a fonctionné pour moi aussi. Est-ce en fait un bug? – mvexel

+0

J'ai eu le même problème une feuille d'action. Cette solution de contournement l'a corrigé. Merci! –

+2

Ce bug devrait être résolu à partir de iOS SDK 4.2. J'ai pu confirmer la résolution d'Apple. – gorbster

4

J'ai eu le même problème, et je remarqué le deuxième événement a eu l'état UIGestureRecognizerStateCancelled (alors que la première était UIGestureRecognizerStateEnded), donc une autre solution consiste à ignorer l'événement ce cas.

-1

Je l'ai fait et travaillé:

d'abord initialiser un membre de votre objet de manipulation qui stocke le dernier coup NSTimeInterval

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

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


     lastSwipe = 0; 
    } 
    return self; 

} 

Ensuite, ajoutez ce code à votre méthode

-(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

Gesture les reconnaisseurs envoient une action avec un état de geste différent. Donc ce n'est pas un bug. Solution est:

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

j'avais un double UIAlertView se présentent. Comme l'a montré Nicolas Rostov ci-dessus, cela a fonctionné pour moi. Les états UIGestureRecognizerStateEnded et UIGestureRecognizerStateRecognized ont créé une nouvelle alerte lorsque [alertView show] a été utilisée dans le bloc. Avec // [alertView show] commenté, les deux sont toujours apparus sur la console, mais une seule action a eu lieu.

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

Cela invoquera le alertview immédiatement après l'événement geste. par exemple: si vous utilisez l'événement longtap, la vue d'alerte s'affichera lorsque vous retirez votre doigt. Mais l'état UIGestureRecognizerStateBegan sera appelé automatiquement si le geste est reconnu automatiquement.

3

Je viens de résoudre un problème similaire. Il s'est avéré que j'avais deux reconnaisseurs de gestes de robinet ajoutés à la vue avec le même appel. La façon dont j'ai découvert est en NSLogging le reconnaisseur de gestes lorsque le sélecteur est appelé.

À votre place, je vérifierais que vous n'avez pas deux identificateurs de gestes - un venant du storyboard, et un autre créé par programmation par exemple.

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

bon conseil. tnxx – user1105951