Наблюдение за положением скорости в 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];
}
}