UILongPressGestureRecognizer вызывается дважды при нажатии

Я определяю, нажал ли пользователь в течение 2 секунд:

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

Вот как я справляюсь с долгим нажатием:

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

Текст «double oo» печатается дважды, когда я нажимаю на него дольше 2 секунд. Почему это? Как исправить?


person Sheehan Alam    schedule 23.07.2010    source источник


Ответы (7)


UILongPressGestureRecognizer - это средство распознавания непрерывных событий. Вы должны посмотреть на состояние, чтобы увидеть, является ли это началом, серединой или концом события, и действовать соответственно. т.е. вы можете выбросить все события после старта или смотреть только на движение, как вам нужно. Из справочника по классам:

Жесты при длительном нажатии продолжаются. Жест начинается (UIGestureRecognizerStateBegan), когда количество разрешенных пальцев (numberOfTouchesRequired) нажато в течение указанного периода (minimumPressDuration) и касания не выходят за пределы допустимого диапазона движения (allowableMovement). Распознаватель жестов переходит в состояние «Изменить» при каждом движении пальца и заканчивается (UIGestureRecognizerStateEnded), когда поднимается любой из пальцев.

Теперь вы можете отслеживать состояние вот так

-  (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
     }
  }
person joelm    schedule 23.07.2010
comment
Следующий ответ показывает, как это сделать, но я дал этому ответу +1 из-за его подробного объяснения и ссылки на документацию. - person Matt Connolly; 23.03.2011
comment
Может быть более полезным с примером кода, чем просто ссылка на документацию. Я разместил свой фрагмент кода ниже. проверьте состояние UIGestureRecognizerStateBegan. - person Paul Solt; 19.08.2011
comment
UIGestureRecognizerStateChanged - person Rajneesh071; 12.03.2013
comment
@joelm ты меня спас) - person Evgeniy Kleban; 01.11.2017
comment
Для Swift 4: if (sender.state == UITapGestureRecognizer.State.ended) {// Делайте все, что хотите, в конце жеста print (\ n * longpressed * \ n)} - person Ravi; 11.10.2018

Чтобы проверить состояние UILongPressGestureRecognizer, просто добавьте оператор if в метод селектора:

- (void)handleLongPress:(UILongPressGestureRecognizer *)sender {    
    if (sender.state == UIGestureRecognizerStateEnded) {
        NSLog(@"Long press Ended");
    } else if (sender.state == UIGestureRecognizerStateBegan) {
        NSLog(@"Long press detected.");
    }
}
person Dan    schedule 11.11.2010
comment
Вам не нужен этот блок if / else, так как состояний больше, чем Ended. Обнаружено долгое нажатие будет напечатано несколько раз при изменении состояния. Вместо этого проверьте состояние UIGestureRecognizerStateBegan. - person Paul Solt; 19.08.2011
comment
Кто-то действительно должен отредактировать этот ответ, чтобы он соответствовал тому, что говорится в верхнем комментарии. В нынешнем виде предоставленный код не работает. - person Declan McKenna; 12.09.2012

Вам необходимо проверить правильность состояния, поскольку для каждого состояния существует разное поведение. Скорее всего, вам понадобится состояние UIGestureRecognizerStateBegan с 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
    }
}
person Paul Solt    schedule 18.08.2011
comment
Похоже, вам нужно пошевелить пальцами, чтобы состояние изменилось; это верно? - person Arcadian; 18.01.2012
comment
Он может вызвать StateChanged при перемещении пальцев, что похоже на то, что я делал в своем тестовом коде. - person Paul Solt; 20.01.2012
comment
Кажется, что UIGestureRecognizerStateBegan вызывается только один раз, что идеально подходит для моей ситуации, пытаясь показать диалог при обнаружении длительного нажатия на кнопку. Другие состояния вызываются несколько раз. Спасибо! - person Damian; 09.03.2012

Просто попробуйте это:

Цель-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.");
        }
}
person Rajesh Loganathan    schedule 07.09.2015

Swift 3.0:

func handleLongPress(sender: UILongPressGestureRecognizer) {

    if sender.state == .ended {
        print("Long press Ended")
    } else if sender.state == .began {
        print("Long press detected")
    }
person fozoglu    schedule 26.11.2016

Вот как с этим справиться в Swift:

func longPress(sender:UILongPressGestureRecognizer!) {

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

ваш обработчик жестов получает вызов для каждого состояния жеста. поэтому вам нужно поставить галочку для каждого состояния и перевести код в требуемое состояние.

Следует предпочесть использование switch-case вместо 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;
         }
}
person Pankaj Wadhwa    schedule 04.04.2014