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?
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!
No timers needed. You can achieve it this way:
- (void)handleRecognizer:(UILongPressGestureRecognizer *)gesture
{
static NSTimeInterval pressStartTime = 0.0; //This can be moved out and 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 the gesture recognizer's minimumPressDuration
to 0
while creating it, if you want to get the real duration of the long press:myLongPressGestureRecognizer.minimumPressDuration = 0
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.
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.
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
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With