依赖于速度的观察UIPanGestureRecognizer
:我不知道你的经验,但我发现系统在模拟器上生成的速度并不是非常有用。(在设备上没问题,但在模拟器上有问题。)
如果您快速平移并突然停止,等待,然后才结束手势(例如,用户开始滑动,意识到这不是他们想要的,所以他们停止然后松开手指),速度报告velocityInView:
为UIGestureRecognizerStateEnded
松开手指时的状态似乎是我停下来等待之前的快速速度,而本例中的正确速度将为零(或接近零)。简而言之,报告的速度是平底锅末端之前的速度,而不是平底锅末端本身的速度。
我最终自己手动计算了速度。(这似乎很愚蠢,但如果我真的想获得平底锅的最终速度,我没有看到任何解决方法。)底线,当状态是UIGestureRecognizerStateChanged
我跟踪当前和以前的translationInView
CGPoint 为以及时间,然后使用这些值UIGestureRecognizerStateEnded
来计算实际的最终速度。它工作得很好。
这是我计算速度的代码。我碰巧没有使用速度来计算动画的速度,而是使用它来确定用户是否平移足够远或轻弹足够快以使视图在屏幕上移动超过一半,因此触发视图之间的动画,但计算最终速度的概念似乎适用于这个问题。这是代码:
- (void)handlePanGesture:(UIPanGestureRecognizer *)gesture
{
static CGPoint lastTranslate; // the last value
static CGPoint prevTranslate; // the value before that one
static NSTimeInterval lastTime;
static NSTimeInterval prevTime;
CGPoint translate = [gesture translationInView:self.view];
if (gesture.state == UIGestureRecognizerStateBegan)
{
lastTime = [NSDate timeIntervalSinceReferenceDate];
lastTranslate = translate;
prevTime = lastTime;
prevTranslate = lastTranslate;
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
prevTime = lastTime;
prevTranslate = lastTranslate;
lastTime = [NSDate timeIntervalSinceReferenceDate];
lastTranslate = translate;
[self moveSubviewsBy:translate];
}
else if (gesture.state == UIGestureRecognizerStateEnded)
{
CGPoint swipeVelocity = CGPointZero;
NSTimeInterval seconds = [NSDate timeIntervalSinceReferenceDate] - prevTime;
if (seconds)
{
swipeVelocity = CGPointMake((translate.x - prevTranslate.x) / seconds, (translate.y - prevTranslate.y) / seconds);
}
float inertiaSeconds = 1.0; // let's calculate where that flick would take us this far in the future
CGPoint final = CGPointMake(translate.x + swipeVelocity.x * inertiaSeconds, translate.y + swipeVelocity.y * inertiaSeconds);
[self animateSubviewsUsing:final];
}
}