iOS:如何获得长按手势的持续时间?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9419041/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS: How to get duration of long press gesture?
提问by Ryan Dao
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:
我正在开发一个游戏,其中通过长按对象本身来设置游戏对象的属性。该属性的值由长按手势的持续时间决定。我为此目的使用 UILongPressGestureRecognizer,所以它是这样的:
[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?
在这种情况下,如何获得长按手势的持续时间?
回答by Rupert Horlick
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.
我很确定手势不会存储此信息供您访问。您只能在其上设置一个名为 minimumPressDuration 的属性,该属性是识别手势之前的时间量。
Workaround with ios 5 (untested):
ios 5 的解决方法(未经测试):
Create an NSTimer property called timer: @property (nonatomic, strong) NSTimer *timer;
创建一个名为 timer 的 NSTimer 属性: @property (nonatomic, strong) NSTimer *timer;
And a counter: @property (nonatomic, strong) int counter;
还有一个计数器: @property (nonatomic, strong) int counter;
Then @synthesize
然后 @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!
因此,当手势开始时,启动一个计时器,每秒触发一次增量方法,直到手势结束。在这种情况下,您需要将 设置minimumPressDuration
为 0,否则手势不会立即开始。然后用计数器做任何你想做的事!
回答by Just Shadow
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
另外不要忘记设置手势识别的minimumPressDuration
,以0
在创建它,如果你想获得长按真正的持续时间:myLongPressGestureRecognizer.minimumPressDuration = 0
回答by SafeFastExpressive
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.
到目前为止,面向对象的 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")
}
}
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.
如果你想包括第一次点击的时间,你可以在计算持续时间时包括它,通过添加手势.minimumPressDuration。缺点是它可能不是微秒精确,因为手势被触发和你的 .Start 处理程序被调用之间可能有一小段(微小的)时间流逝。但是对于绝大多数应用程序来说应该无关紧要。
回答by fbernardo
See the "minimumPressDuration" property. According to the documentation:
请参阅“minimumPressDuration”属性。根据文档:
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.
手指必须按在视图上的最短周期才能识别手势。
[...]
时间间隔以秒为单位。默认持续时间为 0.5 秒。
回答by inVINCEable
I know this is a late answer but this works perfectly for me in IOS 7 & 8 without having to create a timer.
我知道这是一个迟到的答案,但这在 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
回答by Janmenjaya
You can get it by Following in Swift 3.0
您可以通过在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
}
回答by Liron Berger
It seems that with new iOS versions (10 for me at the moment), the long press recognizer callbacks for both the .begin
and .ended
states happen one after the other, only after the event has ended, that is only when you raise your finger from the screen.
似乎在新的 iOS 版本(目前对我来说是 10 个)中,.begin
和.ended
状态的长按识别器回调一个接一个地发生,只有在事件结束后,也就是当你从屏幕上抬起手指时.
That makes the difference between the two events be fractions of milliseconds, and not what you were actually searching for.
这使得两个事件之间的差异只有几毫秒,而不是您实际搜索的内容。
Until this will be fixed, I decided to create another gesture recognizer from scratch in swift, and that would be its working skeleton.
在解决这个问题之前,我决定从头开始创建另一个手势识别器,这将是它的工作框架。
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
}
}
Then you can access the .duration
property of the LongPressDurationGestureRecognizer
gesture recognizer easily.
然后您可以轻松访问手势识别器的.duration
属性LongPressDurationGestureRecognizer
。
For instance:
例如:
func handleLongPressDuration(_ sender: LongPressDurationGestureRecognizer) {
print(sender.duration)
}
This specific example, doesn't take into consideration how many touches actually took place, or their location. But you can easily play with it, extending the LongPressDurationGestureRecognizer.
这个具体的例子没有考虑实际发生了多少次触摸,或者它们的位置。但是您可以轻松地使用它,扩展 LongPressDurationGestureRecognizer。