UILongPressGestureRecognizer viene chiamato due volte quando si preme verso il basso


359

Sto rilevando se l'utente ha premuto per 2 secondi:

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

Ecco come gestisco la lunga pressione:

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

Il testo "double oo" viene stampato due volte quando premo per più di 2 secondi. Perchè è questo? Come posso risolvere?

Risposte:


684

UILongPressGestureRecognizer è un riconoscimento di eventi continuo. Devi guardare lo stato per vedere se questo è l'inizio, la metà o la fine dell'evento e agire di conseguenza. vale a dire che puoi buttare via tutti gli eventi dopo l'inizio o guardare il movimento di cui hai bisogno. Dal riferimento di classe :

I gesti a pressione prolungata sono continui. Il gesto inizia (UIGestureRecognizerStateBegan) quando il numero di dita consentite (numberOfTouchesRequired) è stato premuto per il periodo specificato (MinimumPressDuration) e i tocchi non si spostano oltre l'intervallo di movimento consentito (allowableMovement). Il riconoscimento gesti passa allo stato Modifica ogni volta che si muove un dito e termina (UIGestureRecognizerStateEnded) quando una delle dita viene sollevata.

Ora puoi monitorare lo stato in questo modo

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

4
La prossima risposta in basso mostra come farlo, ma ho dato a questa risposta il +1 a causa della sua spiegazione dettagliata e del collegamento alla documentazione.
Matt Connolly,

2
Potrebbe essere più utile con un esempio di codice, piuttosto che collegando solo alla documentazione. Di seguito ho pubblicato il mio frammento di codice. controlla lo stato UIGestureRecognizerStateBegan.
Paul Solt,

UIGestureRecognizerStateChanged
Rajneesh071

@joelm mi hai salvato)
Evgeniy Kleban

Per Swift 4: if (sender.state == UITapGestureRecognizer.State.ended) {// Fai quello che vuoi sulla stampa di End of Gesture ("\ n * longpressed * \ n")}
Ravi

117

Per controllare lo stato di UILongPressGestureRecognizer basta aggiungere un'istruzione if sul metodo di selezione:

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

13
Non vuoi che if / else blocchi, poiché ci sono più stati di Ended. "Pressione prolungata rilevata" verrà stampata più volte quando lo stato cambia. Controlla invece lo stato UIGestureRecognizerStateBegan.
Paul Solt,

2
Qualcuno dovrebbe davvero modificare quella risposta per adattarsi a ciò che dice il commento in alto. Allo stato attuale il codice fornito non funziona.
Declan McKenna,

75

È necessario controllare lo stato corretto, poiché esistono comportamenti diversi per ogni stato. Molto probabilmente avrai bisogno dello UIGestureRecognizerStateBeganstato con il 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
    }
}

2
Sembra che devi muovere le dita per far cambiare lo stato; è corretto?
Arcadian,

Potrebbe innescare StateChanged quando si spostano le dita, il che sembra simile a quello che stavo facendo nel mio codice di test.
Paul Solt,

UIGestureRecognizerStateBegan sembra essere chiamato solo una volta, il che è perfetto per la mia situazione, cercando di mostrare una finestra di dialogo sul rilevamento di una lunga pressione su un pulsante. Gli altri stati vengono chiamati più volte. Grazie!
Damian,

19

Prova questo:

Objective-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.");
        }
}

14

Ecco come gestirlo in Swift:

func longPress(sender:UILongPressGestureRecognizer!) {

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

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")
    }

6

il gestore dei gesti riceve una chiamata per ogni stato del gesto. quindi devi mettere un segno di spunta per ogni stato e mettere il tuo codice nello stato richiesto.

Bisogna preferire l'uso di switch-case piuttosto che 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;
         }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.