UILongPressGestureRecognizer est appelé deux fois en appuyant sur

359

Je détecte si l'utilisateur a appuyé pendant 2 secondes:

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
                                             initWithTarget:self 
                                             action:@selector(handleLongPress:)];
        longPress.minimumPressDuration = 2.0;
        [self addGestureRecognizer:longPress];
        [longPress release];

Voici comment je gère la pression longue:

-(void)handleLongPress:(UILongPressGestureRecognizer*)recognizer{
    NSLog(@"double oo");
}

Le texte "double oo" est imprimé deux fois lorsque j'appuie pendant plus de 2 secondes. Pourquoi est-ce? Comment puis-je réparer?

Sheehan Alam
la source

Réponses:

684

UILongPressGestureRecognizer est un identificateur d'événements continu. Vous devez regarder l'état pour voir si c'est le début, le milieu ou la fin de l'événement et agir en conséquence. c'est-à-dire que vous pouvez jeter tous les événements après le départ, ou ne regarder que les mouvements selon vos besoins. De la référence de classe :

Les gestes de pression longue sont continus. Le geste commence (UIGestureRecognizerStateBegan) lorsque le nombre de doigts autorisés (numberOfTouchesRequired) a été enfoncé pendant la période spécifiée (minimumPressDuration) et que les touches ne dépassent pas la plage de mouvement autorisée (allowableMovement). L'identificateur de gestes passe à l'état Changer chaque fois qu'un doigt bouge et se termine (UIGestureRecognizerStateEnded) lorsque l'un des doigts est levé.

Vous pouvez maintenant suivre l'état comme ceci

-  (void)handleLongPress:(UILongPressGestureRecognizer*)sender { 
    if (sender.state == UIGestureRecognizerStateEnded) {
      NSLog(@"UIGestureRecognizerStateEnded");
    //Do Whatever You want on End of Gesture
     }
    else if (sender.state == UIGestureRecognizerStateBegan){
       NSLog(@"UIGestureRecognizerStateBegan.");
   //Do Whatever You want on Began of Gesture
     }
  }
joelm
la source
4
La réponse suivante montre comment le faire, mais j'ai donné cette réponse +1 en raison de son explication détaillée et de son lien vers la documentation.
Matt Connolly
2
Pourrait être plus utile avec un exemple de code, plutôt que de lier uniquement à la documentation. J'ai publié mon extrait de code ci-dessous. vérifiez l'état UIGestureRecognizerStateBegan.
Paul Solt
UIGestureRecognizerStateChanged
Rajneesh071
@joelm tu m'as sauvé)
Evgeniy Kleban
Pour Swift 4: if (sender.state == UITapGestureRecognizer.State.ended) {// Faites ce que vous voulez à la fin de l'impression ("\ n * longpressed * \ n")}
Ravi
117

Pour vérifier l'état de UILongPressGestureRecognizer, ajoutez simplement une instruction if sur la méthode de sélection:

- (void)handleLongPress:(UILongPressGestureRecognizer *)sender {    
    if (sender.state == UIGestureRecognizerStateEnded) {
        NSLog(@"Long press Ended");
    } else if (sender.state == UIGestureRecognizerStateBegan) {
        NSLog(@"Long press detected.");
    }
}
Dan
la source
13
Vous ne voulez pas que le bloc if / else, car il y a plus d'états que Ended. "Pression longue détectée" s'imprime plusieurs fois lorsque l'état change. Vérifiez plutôt l'état UIGestureRecognizerStateBegan.
Paul Solt
2
Quelqu'un devrait vraiment modifier cette réponse pour qu'elle corresponde à ce que dit le premier commentaire. En l'état, le code fourni ne fonctionne pas.
Declan McKenna
75

Vous devez vérifier l'état correct, car il existe différents comportements pour chaque état. Vous aurez probablement besoin de l' UIGestureRecognizerStateBeganÉtat avec le UILongPressGestureRecognizer.

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
                                             initWithTarget:self 
                                             action:@selector(handleLongPress:)];
longPress.minimumPressDuration = 1.0;
[myView addGestureRecognizer:longPress];
[longPress release];

...

- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture {
    if(UIGestureRecognizerStateBegan == gesture.state) {
        // Called on start of gesture, do work here
    }

    if(UIGestureRecognizerStateChanged == gesture.state) {
        // Do repeated work here (repeats continuously) while finger is down
    }

    if(UIGestureRecognizerStateEnded == gesture.state) {
        // Do end work here when finger is lifted
    }
}
Paul Solt
la source
2
On dirait que vous devez déplacer vos doigts pour que l'état change; Est-ce exact?
Arcadian
Cela pourrait déclencher StateChanged lors du déplacement des doigts, ce qui ressemble à ce que je faisais dans mon code de test.
Paul Solt
UIGestureRecognizerStateBegan ne semble être appelé qu'une seule fois, ce qui est parfait pour ma situation en essayant d'afficher une boîte de dialogue sur la détection d'un appui long sur un bouton. Les autres États sont appelés plusieurs fois. Merci!
Damian
19

Essayez ceci:

Objectif c

- (void)handleLongPress:(UILongPressGestureRecognizer*)sender { 
    if (sender.state == UIGestureRecognizerStateEnded) {
        NSLog(@"Long press Ended");
    } else if (sender.state == UIGestureRecognizerStateBegan) {
        NSLog(@"Long press detected.");
    }
}

Swift 2.2:

func handleLongPress(sender:UILongPressGestureRecognizer) {

        if (sender.state == UIGestureRecognizerState.Ended) {
            print("Long press Ended");
        } else if (sender.state == UIGestureRecognizerState.Began) {
            print("Long press detected.");
        }
}
Rajesh Loganathan
la source
14

Voici comment le gérer dans Swift:

func longPress(sender:UILongPressGestureRecognizer!) {

        if (sender.state == UIGestureRecognizerState.Ended) {
            println("Long press Ended");
        } else if (sender.state == UIGestureRecognizerState.Began) {
            println("Long press detected.");
        }
}
Raj
la source
13

Swift 3.0:

func handleLongPress(sender: UILongPressGestureRecognizer) {

    if sender.state == .ended {
        print("Long press Ended")
    } else if sender.state == .began {
        print("Long press detected")
    }
fozoglu
la source
6

votre gestionnaire de gestes reçoit un appel pour chaque état de geste. vous devez donc mettre un chèque pour chaque état et mettre votre code dans l'état requis.

Il faut préférer utiliser switch-case plutôt que if-else:

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
                                         initWithTarget:self 
                                         action:@selector(handleLongPress:)];
    longPress.minimumPressDuration = 1.0;
    [myView addGestureRecognizer:longPress];
    [longPress release];

-(void)handleLongPress:(UILongPressGestureRecognizer *)gesture {
        switch(gesture.state){
          case UIGestureRecognizerStateBegan:
               NSLog(@"State Began");
               break;
          case UIGestureRecognizerStateChanged:
               NSLog(@"State changed");
               break;
          case UIGestureRecognizerStateEnded:
               NSLog(@"State End");
               break;
          default:
               break;
         }
}
Pankaj Wadhwa
la source