【问题标题】:UILongPressGestureRecognizer gets called twice when pressing down按下时 UILongPressGestureRecognizer 被调用两次
【发布时间】:2011-03-20 04:12:02
【问题描述】:

我正在检测用户是否按下了 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”会打印两次。为什么是这样?我该如何解决?

【问题讨论】:

    标签: iphone objective-c cocoa-touch gesture-recognition uigesturerecognizer


    【解决方案1】:

    UILongPressGestureRecognizer 是一个连续事件识别器。您必须查看状态以查看这是事件的开始、中间还是结束,并采取相应的行动。即您可以在开始后丢弃所有事件,或者仅根据需要查看运动。来自Class Reference

    长按手势是连续的。当允许的手指数量 (numberOfTouchesRequired) 在指定的时间 (minimumPressDuration) 内被按下并且触摸没有超出允许的移动范围 (allowableMovement) 时,手势开始 (UIGestureRecognizerStateBegan)。每当手指移动时,手势识别器就会转换到 Change 状态,并在任何手指抬起时结束 (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
         }
      }
    

    【讨论】:

    • 下一个答案显示了如何做到这一点,但我给了这个答案+1,因为它有详细的解释和文档链接。
    • 可能对代码示例更有帮助,而不是仅链接到文档。我在下面发布了我的代码 sn-p。检查 UIGestureRecognizerStateBegan 状态。
    • UIGestureRecognizerStateChanged
    • @joelm 你救了我)
    • 对于 Swift 4: if (sender.state == UITapGestureRecognizer.State.ended ) { //在手势结束时做任何你想做的事情 print("\n * longpressed *\n") }
    【解决方案2】:

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

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

    【讨论】:

    • 你不想要那个 if/else 块,因为有比 Ended 更多的状态。当状态改变时,“检测到长按”会打印多次。检查 UIGestureRecognizerStateBegan 状态。
    • 应该有人真正编辑该答案以符合最高评论所说的内容。就目前而言,提供的代码不起作用。
    【解决方案3】:

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

    【讨论】:

    • 似乎你必须移动手指才能改变状态;对吗?
    • 它可能会在移动手指时触发 StateChanged,这听起来类似于我在测试代码中所做的。
    • UIGestureRecognizerStateBegan 似乎只被调用一次,这非常适合我试图在检测长按按钮时显示对话框的情况。其他州被多次调用。谢谢!
    【解决方案4】:

    试试这个:

    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.");
            }
    }
    

    【讨论】:

      【解决方案5】:

      斯威夫特 3.0:

      func handleLongPress(sender: UILongPressGestureRecognizer) {
      
          if sender.state == .ended {
              print("Long press Ended")
          } else if sender.state == .began {
              print("Long press detected")
          }
      

      【讨论】:

        【解决方案6】:

        这里是如何在 Swift 中处理它:

        func longPress(sender:UILongPressGestureRecognizer!) {
        
                if (sender.state == UIGestureRecognizerState.Ended) {
                    println("Long press Ended");
                } else if (sender.state == UIGestureRecognizerState.Began) {
                    println("Long press detected.");
                }
        }
        

        【讨论】:

          【解决方案7】:

          您的手势处理程序接收每个手势状态的调用。所以你需要检查每个状态并将你的代码置于所需的状态。

          人们必须更喜欢使用 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;
                   }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-12-10
            • 1970-01-01
            • 1970-01-01
            • 2017-09-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-01
            相关资源
            最近更新 更多