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.