如何确定平底手势的真实最终速度?

当使用UIPanGestureRecognizer并检测到UIGestureRecognizerStateEnded ,手势的速度不是真实的速度。 相反,这是以前调用我的操作方法的旧速度。 我怎样才能访问手势结束时的真实速度?

我创build我的UIPanGestureRecognizer像这样:

  UIPanGestureRecognizer* panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureRecognized:)]; [panGestureRecognizer setMaximumNumberOfTouches:2]; [panGestureRecognizer setMinimumNumberOfTouches:1]; [panGestureRecognizer setDelegate:self]; [panGestureRecognizer setDelaysTouchesBegan:NO]; [panGestureRecognizer setDelaysTouchesEnded:NO]; [panGestureRecognizer setCancelsTouchesInView:NO]; [self addGestureRecognizer:panGestureRecognizer]; 

我的行动方法的开始在这里:

 - (IBAction) panGestureRecognized:(UIPanGestureRecognizer *)recognizer { UIGestureRecognizerState state = recognizer.state; CGPoint gestureTranslation = [recognizer translationInView:self]; CGPoint gestureVelocity = [recognizer velocityInView:self]; [CBAppDelegate log:@"panGestureRecognized: state: %s\n translation: (%f, %f)\n velocity: (%f, %f)", [self toString:state], gestureTranslation.x, gestureTranslation.y, gestureVelocity.x, gestureVelocity.y]; 

日志输出示例:

 2013-09-30_10:46:32.830 panGestureRecognized: state: UIGestureRecognizerStateChanged translation: (-283.000000, 2.000000) velocity: (-43.046783, 45.551472) 2013-09-30_10:47:02.942 panGestureRecognized: state: UIGestureRecognizerStateEnded translation: (-283.000000, 2.000000) velocity: (-43.046783, 45.551472) 

正如你所看到的,两个日志条目的速度是相同的(同样的故事与翻译,但我只关心速度),虽然我是按住我的手指约30秒没有移动,然后举起手指。 您可以从条目的时间戳中确定时间。 没有移动我的手指30秒后肯定没有报告的速度。

我已经用iOS 6.1的iPhone模拟器testing了这个。

velocityInView方法仅在发生平移时定义。 也就是说,只有当你实际移动手指时,平移手势才会发生。 如果你保持手指不动,它实际上不会触发平移手势。

这意味着在手势结束时没有内置的方法来知道移动速度。 你可以做一些事情,例如检查上次事件与状态值之间的时间差异,如UIGestureRecognizerStateChangedUIGestureRecognizerStateEnded 。 然后,您可以调整此阈值以获得所需的行为。

例如

 - (IBAction) panGestureRecognized:(UIPanGestureRecognizer *)recognizer { UIGestureRecognizerState state = recognizer.state; CGPoint gestureTranslation = [recognizer translationInView:self]; CGPoint gestureVelocity = [recognizer velocityInView:self]; if ( state == UIGestureRecognizerStateChanged ) _lastChange = CFAbsoluteTimeGetCurrent(); else if ( state == UIGestureRecognizerStateEnded ) { double curTime = CFAbsoluteTimeGetCurrent(); double timeElapsed = curTime - _lastChange; if ( timeElapsed < MY_THRESHOLD ) finalSpeed = gestureVelocity; else finalSpeed = CGPointZero; } }