UILongPressGestureRecognizer wird beim Drücken zweimal aufgerufen


359

Ich erkenne, ob der Benutzer 2 Sekunden lang gedrückt hat:

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

So gehe ich mit der langen Presse um:

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

Der Text "double oo" wird zweimal gedruckt, wenn ich länger als 2 Sekunden drücke. Warum ist das? Wie kann ich das beheben?

Antworten:


684

UILongPressGestureRecognizer ist eine kontinuierliche Ereigniserkennung. Sie müssen den Status überprüfen, um festzustellen, ob dies der Beginn, die Mitte oder das Ende des Ereignisses ist, und entsprechend handeln. Das heißt, Sie können alle Ereignisse nach dem Start wegwerfen oder die Bewegung nur nach Bedarf betrachten. Aus der Klassenreferenz :

Langes Drücken ist kontinuierlich. Die Geste beginnt (UIGestureRecognizerStateBegan), wenn die Anzahl der zulässigen Finger (numberOfTouchesRequired) für den angegebenen Zeitraum gedrückt wurde (MinimumPressDuration) und die Berührungen den zulässigen Bewegungsbereich (allowableMovement) nicht überschreiten. Der Gestenerkenner wechselt bei jeder Bewegung eines Fingers in den Status Ändern und endet (UIGestureRecognizerStateEnded), wenn einer der Finger angehoben wird.

Jetzt können Sie den Zustand so verfolgen

-  (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
Die nächste Antwort unten zeigt, wie es geht, aber ich habe dieser Antwort aufgrund ihrer detaillierten Erklärung und des Links zur Dokumentation die +1 gegeben.
Matt Connolly

2
Könnte bei einem Codebeispiel hilfreicher sein, als nur auf die Dokumentation zu verlinken. Ich habe mein Code-Snippet unten gepostet. Überprüfen Sie den Status UIGestureRecognizerStateBegan.
Paul Solt

UIGestureRecognizerStateChanged
Rajneesh071

@joelm du hast mich gerettet)
Evgeniy Kleban

Für Swift 4: if (sender.state == UITapGestureRecognizer.State.ended) {// Mach was du willst am Ende des Gestenabdrucks ("\ n * lang gedrückt * \ n")}
Ravi

117

Um den Status des UILongPressGestureRecognizer zu überprüfen, fügen Sie einfach eine if-Anweisung zur Selector-Methode hinzu:

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

13
Sie möchten diesen if / else-Block nicht, da es mehr Status als Ended gibt. "Langes Drücken erkannt" wird mehrmals gedruckt, wenn sich der Status ändert. Überprüfen Sie stattdessen den Status UIGestureRecognizerStateBegan.
Paul Solt

2
Jemand sollte diese Antwort wirklich so bearbeiten, dass sie mit dem übereinstimmt, was der oberste Kommentar sagt. Der bereitgestellte Code funktioniert derzeit nicht.
Declan McKenna

75

Sie müssen den richtigen Status überprüfen, da es für jeden Status unterschiedliche Verhaltensweisen gibt. Höchstwahrscheinlich werden Sie den UIGestureRecognizerStateBeganStaat mit dem brauchen 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
Scheint, als müssten Sie Ihre Finger bewegen, um den Zustand zu ändern. Ist das korrekt?
Arcadian

Es könnte StateChanged auslösen, wenn Sie die Finger bewegen. Das klingt ähnlich wie in meinem Testcode.
Paul Solt

UIGestureRecognizerStateBegan scheint nur einmal aufgerufen zu werden, was perfekt für meine Situation ist, in der versucht wird, einen Dialog zum Erkennen eines langen Tastendrucks anzuzeigen. Die anderen Zustände werden mehrfach aufgerufen. Vielen Dank!
Damian

19

Versuchen Sie einfach Folgendes:

Ziel 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

So geht's 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

Ihr Gestenhandler erhält einen Anruf für jeden Gestenstatus. Sie müssen also für jeden Status eine Prüfung durchführen und Ihren Code in den erforderlichen Status versetzen.

Man muss es vorziehen, Switch-Case gegenüber if-else zu verwenden:

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;
         }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.