按下时会两次调用UILongPressGestureRecognizer


359

我正在检测用户是否已按下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");
}

当我按下2秒钟以上时,文本“ double oo”被打印两次。为什么是这样?我该如何解决?

Answers:


684

UILongPressGestureRecognizer是连续事件识别器。您必须查看状态以查看这是事件的开始,中间还是结束,并采取相应的措施。即,您可以在开始之后放弃所有事件,或者仅根据需要查看运动。从 类参考

长按手势是连续的。当在指定的时间段(minimumPressDuration)内按下了允许的手指数(numberOfTouchesRequired),并且触摸未移动到允许的移动范围(allowableMovement)范围内时,手势开始(UIGestureRecognizerStateBegan)。每当手指移动时,手势识别器都会转换为“更改”状态,并且在任何手指抬起时手势识别器都会终止(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
     }
  }

4
下一个答案显示了如何执行此操作,但是由于它的详细说明和指向文档的链接,因此我将此答案设为+1。
马特·康诺利

2
使用代码示例可能会更有帮助,而不是仅链接到文档。我在下面发布了我的代码段。检查UIGestureRecognizerStateBegan状态。
保罗·索尔特

UIGestureRecognizerStateChanged
Rajneesh071

@joelm,你救了我))
Evgeniy Kleban '17

对于Swift 4:if(sender.state == UITapGestureRecognizer.State.ended){//在手势结尾处执行任何操作print(“ \ n * longpressed * \ n”)}
Ravi

117

要检查UILongPressGestureRecognizer的状态,只需在选择器方法上添加if语句:

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

13
您不希望if / else阻塞,因为状态多于“已结束”。状态更改时,“检测到长按”将打印多次。请改为检查UIGestureRecognizerStateBegan状态。
Paul Solt

2
有人应该真正编辑该答案,使其与顶部评论中的内容相符。就目前而言,所提供的代码无效。
Declan McKenna

75

您需要检查正确的状态,因为每种状态都有不同的行为。您最有可能需要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
    }
}

2
似乎您必须动动手指才能改变状态。那是对的吗?
Arcadian 2012年

左右移动手指时,它可能会触发StateChanged,这听起来与我在测试代码中所做的类似。
保罗·索尔特

UIGestureRecognizerStateBegan似乎只被调用一次,这对于我的情况非常适合,它试图显示有关检测到长按按钮的对话框。其他状态被多次调用。谢谢!
Damian 2012年

19

尝试一下:

目标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

这是在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

您的手势处理程序会收到每种手势状态的呼叫。因此,您需要检查每个状态并将代码置于必需状态。

必须使用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;
         }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.