UILongPressGestureRecognizer jest wywoływany dwukrotnie po naciśnięciu

359

Wykrywam, czy użytkownik naciskał przez 2 sekundy:

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

Tak sobie radzę z długim naciśnięciem:

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

Tekst „double oo” jest drukowany dwukrotnie, gdy naciskam dłużej niż 2 sekundy. Dlaczego to? Jak mogę to naprawić?

Sheehan Alam
źródło

Odpowiedzi:

684

UILongPressGestureRecognizer to ciągły moduł rozpoznawania zdarzeń. Musisz spojrzeć na stan, aby zobaczyć, czy jest to początek, środek czy koniec wydarzenia i odpowiednio postępować. tzn. możesz wyrzucić wszystkie zdarzenia po starcie lub tylko patrzeć na ruch w miarę potrzeb. Z odniesienia do klasy :

Gesty długo naciśnięte są ciągłe. Gest rozpoczyna się (UIGestureRecognizerStateBegan), gdy liczba dozwolonych palców (numberOfTouchesRequired) została naciśnięta przez określony czas (minimumPressDuration), a dotknięcia nie wykraczają poza dopuszczalny zakres ruchu (allowableMovement). Rozpoznawanie gestów przechodzi w stan Zmień za każdym razem, gdy porusza się palec, i kończy się (UIGestureRecognizerStateEnded) po podniesieniu dowolnego palca.

Teraz możesz śledzić stan w ten sposób

-  (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
źródło
4
Następna odpowiedź pokazuje, jak to zrobić, ale dałem tej odpowiedzi +1 ze względu na jej szczegółowe wyjaśnienie i link do dokumentacji.
Matt Connolly,
2
Przydałby się bardziej przykład kodu, niż linkowanie tylko do dokumentacji. Mój fragment kodu zamieściłem poniżej. sprawdź stan UIGestureRecognizerStateBegan.
Paul Solt
UIGestureRecognizerStateChanged
Rajneesh071
@joelm uratowałeś mnie)
Evgeniy Kleban
Dla Swift 4: if (sender.state == UITapGestureRecognizer.State.ended) {// Rób co chcesz na wydruku Gesture („\ n * longpressed * \ n”)}
Ravi
117

Aby sprawdzić stan UILongPressGestureRecognizer, po prostu dodaj instrukcję if do metody selektora:

- (void)handleLongPress:(UILongPressGestureRecognizer *)sender {    
    if (sender.state == UIGestureRecognizerStateEnded) {
        NSLog(@"Long press Ended");
    } else if (sender.state == UIGestureRecognizerStateBegan) {
        NSLog(@"Long press detected.");
    }
}
Dan
źródło
13
Nie chcesz tego blokować jeśli / else, ponieważ istnieje więcej stanów niż Zakończone. „Wykryto długie naciśnięcie” zostanie wydrukowane wiele razy, gdy zmieni się stan. Zamiast tego sprawdź stan UIGestureRecognizerStateBegan.
Paul Solt
2
Ktoś powinien naprawdę edytować tę odpowiedź, aby pasowała do tego, co mówi pierwszy komentarz. W obecnej postaci podany kod nie działa.
Declan McKenna,
75

Musisz sprawdzić poprawny stan, ponieważ dla każdego stanu istnieją różne zachowania. Najprawdopodobniej będziesz potrzebować UIGestureRecognizerStateBeganstanu z 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
źródło
2
Wydaje się, że musisz poruszać palcami, aby zmienić stan; czy to jest poprawne?
Arcadian
Może to powodować zmianę stanu podczas przesuwania palców, co brzmi podobnie do tego, co robiłem w kodzie testowym.
Paul Solt,
UIGestureRecognizerStateBegan wydaje się być wywoływany tylko raz, co jest idealne w mojej sytuacji, gdy próbuję wyświetlić okno dialogowe wykrywania długiego naciśnięcia przycisku. Inne stany są wywoływane wiele razy. Dzięki!
Damian,
19

Po prostu spróbuj tego:

Cel 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
źródło
14

Oto jak sobie z tym poradzić w 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
źródło
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
źródło
6

Twój gest obsługi odbiera połączenie dla każdego stanu gestu. więc musisz sprawdzić każdy stan i ustawić kod w wymaganym stanie.

Trzeba preferować używanie przełączników zamiast 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
źródło