速度に依存することに関する観察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];
}
}