Home » Ios » iOS: How to get duration of long press gesture?

iOS: How to get duration of long press gesture?

Posted by: admin February 24, 2018 Leave a comment

Questions:

I’m working on a game in which an attribute of a game object is set by long pressing on the object itself. The value of the attribute is determined by the duration of the long press gesture. I’m using UILongPressGestureRecognizer for this purpose, so it’s something like this:

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

Then the handler function

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

How do I get the duration of the long press gesture in this case?

Answers:

I’m pretty sure the gesture doesn’t store this information for you to access. You can only set a property on it called minimumPressDuration that is the amount of time before the gesture is recognised.

Workaround with ios 5 (untested):

Create an NSTimer property called timer: @property (nonatomic, strong) NSTimer *timer;

And a counter: @property (nonatomic, strong) int counter;

Then @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];
    }
}

So when the gesture begins start a timer that fires the incrementation method every second until the gesture ends. In this case you’ll want to set the minimumPressDuration to 0 otherwise the gesture won’t start straight away. Then do whatever you want with counter!

Questions:
Answers:

No timers needed. You can achieve it in this way:

- (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;
    }
}

Also don’t forget to set gesture recognizer’s minimumPressDuration to 0 while creating it, if you want to get the real duration of the long press:
myLongPressGestureRecognizer.minimumPressDuration = 0

Questions:
Answers:

It seems by far the cleanest and simplest solution in object oriented Cocoa Touch is to subclass UILongPressGesture. Here is an example written in 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")
            }
    }

If you want to include the time from first tap, you can include it when you calculate duration, by adding back gesture.minimumPressDuration. The drawback is that it is probably not be micro-second precise, given there is likely a small (tiny) amount of time elapsing between the gesture being triggered and your .Start handler being called. But for the vast majority of applications that shouldn’t matter.

Questions:
Answers:

See the “minimumPressDuration” property. According to the documentation:

The minimum period fingers must press on the view for the gesture to
be recognized.

[…]

The time interval is in seconds. The default duration is is 0.5
seconds.

Questions:
Answers:

I know this is a late answer but this works perfectly for me in IOS 7 & 8 without having to create a timer.

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

Questions:
Answers:

You can get it by Following in Swift 3.0

Logic : Just assigning the time of press and find the difference of time when touch ends

Code :

//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
}