【问题标题】:iOS: How to get duration of long press gesture?iOS:如何获取长按手势的持续时间?
【发布时间】:2012-02-23 18:32:37
【问题描述】:

我正在开发一款游戏,其中通过长按对象本身来设置游戏对象的属性。该属性的值由长按手势的持续时间决定。我为此目的使用了 UILongPressGestureRecognizer,所以它是这样的:

[gameObjectView addGestureRecognizer:[[UILongPressGestureRecognizer alloc] 
                                       initWithTarget:self action:@selector(handle:)]];

然后是处理函数

- (void)handle:(UILongPressGestureRecognizer)gesture {
  if (gesture.state == UIGestureRecognizerStateEnded) {
    // Get the duration of the gesture and calculate the value for the attribute
  }
}

在这种情况下如何获取长按手势的持续时间?

【问题讨论】:

    标签: ios uigesturerecognizer


    【解决方案1】:

    我很确定手势不会存储此信息供您访问。您只能在其上设置一个名为 minimumPressDuration 的属性,即识别手势之前的时间量。

    ios 5 的解决方法(未经测试):

    创建一个名为 timer 的 NSTimer 属性:@property (nonatomic, strong) NSTimer *timer;

    还有一个柜台:@property (nonatomic, strong) int counter;

    然后@synthesize

    - (void)incrementCounter {
        self.counter++;
    }
    
    - (void)handle:(UILongPressGestureRecognizer)gesture {
        if (gesture.state == UIGestureRecognizerStateBegan) {
             self.counter = 0;
             self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(incrementCounter) userInfo:nil repeats:yes];
        }
        if (gesture.state == UIGestureRecognizerStateEnded) {
            [self.timer invalidate];
        }
    }
    

    因此,当手势开始时,启动一个计时器,每秒触发一次增量方法,直到手势结束。在这种情况下,您需要将minimumPressDuration 设置为 0,否则手势不会立即开始。然后用计数器做任何你想做的事!

    【讨论】:

    • 检查上面的代码。希望它对你有用!如果您不使用 ios 5,则可能需要进行一些更改。
    • 我只是为了这个目的而避免创建一个属性,但我想没有其他办法了。我使用 NSDate 而不是 NSTimer,因此代码可以更简洁。感谢您的回答!
    • 好极了。谢谢。
    【解决方案2】:

    不需要计时器。您可以通过以下方式实现:

    - (void)handleRecognizer:(UILongPressGestureRecognizer *)gesture
    {
        static NSTimeInterval pressStartTime = 0.0; //This an be moved out and be kept as a property
        
        switch ([gesture state])
        {
            case UIGestureRecognizerStateBegan:
                //Keeping start time...
                pressStartTime = [NSDate timeIntervalSinceReferenceDate];
                break; /* edit*/
            case UIGestureRecognizerStateEnded:
            {
                //Calculating duration
                NSTimeInterval duration = [NSDate timeIntervalSinceReferenceDate] - pressStartTime;
                //Note that NSTimeInterval is a double value...
                NSLog(@"Duration : %f",duration);
                break;
            }
            default:
                break;
        }
    }
    

    另外,如果您想获得长按的实际持续时间,请不要忘记在创建手势识别器时将其minimumPressDuration 设置为0
    myLongPressGestureRecognizer.minimumPressDuration = 0

    【讨论】:

      【解决方案3】:

      目前看来,面向对象的 Cocoa Touch 中最简洁和最简单的解决方案是继承 UILongPressGesture。这是一个用 Swift 编写的示例。

          class MyLongPressGesture : UILongPressGestureRecognizer {
              var startTime : NSDate?
          }
      
          func installGestureHandler() {
                  let longPress = MyLongPressGesture(target: self, action: "longPress:")
                  button.addGestureRecognizer(longPress)
          }
      
          @IBAction func longPress(gesture: MyLongPressGesture) {
                  if gesture.state == .Began {
                          gesture.startTime = NSDate()
                  }
                  else if gesture.state == .Ended {
                          let duration = NSDate().timeIntervalSinceDate(gesture.startTime!)
                          println("duration was \(duration) seconds")
                  }
          }
      

      如果您想包含从第一次点击开始的时间,您可以在计算持续时间时包含它,方法是添加 backgestion.minimumPressDuration。缺点是它可能不是微秒精确的,因为在触发手势和调用 .Start 处理程序之间可能有一小段(微小的)时间。但对于绝大多数应用来说,这无关紧要。

      【讨论】:

        【解决方案4】:

        请参阅“minimumPressDuration”属性。根据文档:

        手指必须在视图上按下手势的最短时间 被认出来。

        [...]

        时间间隔以秒为单位。默认持续时间为 0.5 秒。

        【讨论】:

        • 问题是关于持续时间,即用户手指按住多长时间, minimumPressDuration 用于设置触发手势之前的延迟。
        • 对于那些不想硬编码“幻数”的人,使用它来获得默认值:[UILongPressGestureRecognizer new].minimumPressDuration
        【解决方案5】:

        我知道这是一个迟到的答案,但这对我来说在 IOS 7 和 8 中非常有效,无需创建计时器。

        UILongPressGestureRecognizer *longGR = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(yourAction)]; // create the recognizer
        longGR.minimumPressDuration = 10.0f; //Ten Seconds
        longGR.allowableMovement = 50.0f; //Allowable Movement while being pressed
        [gameObjectView setUserInteractionEnabled:YES]; //If setting interaction to a non-interactable object such as a UIImageView
        [gameObjectView addGestureRecognizer:longGR]; //Add the gesture recognizer to your object
        

        【讨论】:

          【解决方案6】:

          您可以通过关注 Swift 3.0

          获得它

          逻辑:只分配按下的时间,找出触摸结束的时间差

          代码:

          //variable to calculate the press time
          static var pressStartTime: TimeInterval = 0.0
          
          func handleRecognizer(gesture: UILongPressGestureRecognizer) -> Double {
              var duration: TimeInterval = 0
          
              switch (gesture.state) {
              case .began:
                  //Keeping start time...
                  Browser.pressStartTime = NSDate.timeIntervalSinceReferenceDate
          
              case .ended:
                  //Calculating duration
                  duration = NSDate.timeIntervalSinceReferenceDate - Browser.pressStartTime
                  //Note that NSTimeInterval is a double value...
                  print("Duration : \(duration)")
          
              default:
                  break;
              }
          
              return duration
          }
          

          【讨论】:

            【解决方案7】:

            似乎对于新的 iOS 版本(目前为 10 个),.begin.ended 状态的长按识别器回调一个接一个地发生,仅在事件结束后发生,即仅当您从屏幕上抬起手指时。

            这使得两个事件之间的差异只有几分之一毫秒,而不是您实际搜索的内容。

            在解决这个问题之前,我决定用 swift 从头开始​​创建另一个手势识别器,这将是它的工作框架。

            import UIKit.UIGestureRecognizerSubclass
            class LongPressDurationGestureRecognizer : UIGestureRecognizer {
                    private var startTime : Date?
                    private var _duration = 0.0
                    public var duration : Double {
                        get {
                            return _duration
                        }
                    }
                    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
                        startTime = Date() // now
                        state = .begin
                        //state = .possible, if you would like the recongnizer not to fire any callback until it has ended
                    }
                    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
                        _duration = Date().timeIntervalSince(self.startTime!)
                        print("duration was \(duration) seconds")
                        state = .ended
                        //state = .recognized, if you would like the recongnizer not to fire any callback until it has ended
                    }
             }
            

            然后您可以轻松访问LongPressDurationGestureRecognizer 手势识别器的.duration 属性。

            例如:

            func handleLongPressDuration(_ sender: LongPressDurationGestureRecognizer) {
                    print(sender.duration)
            }
            

            这个具体的例子没有考虑实际发生了多少次触摸,或者它们的位置。但是您可以轻松地使用它,扩展 LongPressDurationGestureRecognizer。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2018-01-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-11-05
              • 1970-01-01
              • 2020-07-03
              相关资源
              最近更新 更多