Una observación sobre la dependencia de la velocidad en UIPanGestureRecognizer
: No conozco su experiencia, pero encontré que la velocidad generada por el sistema en el simulador no era demasiado útil. (Está bien en el dispositivo, pero es problemático en el simulador)
Si se desplaza rápidamente y se detiene bruscamente, espera y solo luego finaliza el gesto (por ejemplo, el usuario inicia un desliz, se da cuenta de que esto no era lo que querían) , así que se detienen y luego sueltan el dedo), la velocidad informada por velocityInView:
en el estado UIGestureRecognizerStateEnded
cuando se liberó su dedo parece ser la velocidad rápida antes de detenerse y esperar, mientras que la velocidad correcta en este ejemplo sería cero (o cerca cero). En resumen, la velocidad indicada es la que estaba justo antes del final de la sartén, pero no la velocidad al final de la sartén.
Terminé calculando la velocidad yo mismo, manualmente. (Parece tonto que esto sea necesario, pero no vi ninguna forma de evitarlo si realmente quería obtener la velocidad final de la sartén). En pocas palabras, cuando el estado es UIGestureRecognizerStateChanged
Realizo un seguimiento de la actual y la anterior translationInView
CGPoint, así como la hora, y luego usar esos valores cuando estaba en el UIGestureRecognizerStateEnded
para calcular la velocidad final real. Funciona bastante bien
Aquí está mi código para calcular la velocidad. Resulta que no estoy usando la velocidad para calcular la velocidad de la animación, sino que la estoy usando para determinar si el usuario hizo una panorámica lo suficientemente rápida o la movió lo suficientemente rápido como para que la vista se moviera más allá de la mitad de la pantalla y así desencadenando la animación entre vistas, pero el concepto de calcular la velocidad final parece aplicable a esta pregunta. Aquí está el código:
- (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];
}
}
No funciona en iOS 6 porque la traducción final y la última traducción son las mismas en 'UIGestureRecognizerStateEnded', por lo que la velocidad final es siempre 0. – an0
Gracias, ya veo. Es un problema de simulador. Disparé un informe de error a Apple. – an0
He modificado la fuente (cambiando algunos nombres de variables) para evitar esta confusión. Este código funcionaba bien tal como estaba, pero es de esperar que los nuevos nombres de variable lo hagan un poco menos confuso. Gracias por informar el error a Apple. – Rob