Tengo un conjunto de animaciones UIView
anidadas (2 o 3 niveles de profundidad en un momento dado) que me gustaría poder detener y reanudar. Algunas de estas animaciones usan -animateWithDuration:animations:completion:
, mientras que otras usan -animateWithDuration:delay:options:animations:completion:
para retrasar la ejecución del bloque de animación.Pausar animación CALayer con una animación con un retraso
He leído e implementado Technical Q&A QA1673 sobre pausar todas las animaciones en un árbol de capas, pero estoy teniendo un problema con las animaciones que usan un parámetro de retraso. Puedo pausar y reanudar animaciones muy bien, pero cuando la animación se reanuda, cualquier bloque de animación que tenga un retraso asociado con él parece tener su retraso extendido por la cantidad de tiempo que el árbol de capas estuvo en pausa. Entonces, por ejemplo, si uno de los bloques tiene un retraso de 1 segundo, y el árbol de capas se detuvo por 3 segundos, la animación se retrasa por 4 segundos después de reanudar. Supongo que esto tiene algo que ver con la propiedad beginTime
. Cualquier ayuda sería apreciada.
// Pause and Resume methods, right from the technical Q&A
- (void)pauseAnimationsOnLayer:(CALayer *)layer
{
CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
layer.speed = 0.0;
layer.timeOffset = pausedTime;
}
- (void)resumeAnimationsOnLayer:(CALayer *)layer
{
CFTimeInterval pausedTime = [layer timeOffset];
layer.speed = 1.0;
layer.timeOffset = 0.0;
layer.beginTime = 0;
CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
layer.beginTime = timeSincePause;
}
// Chained animations
- (void)animateNextPopup
{
[UIView animateWithDuration:kRFPVictorySequenceStatePopupDuration
animations:^{
[_currentStateImageView setHidden:NO];
[_currentStateImageView setTransform:CGAffineTransformIdentity];
}
completion:^(BOOL finished) {
[UIView animateWithDuration:kRFPVictorySequenceStateSlideOffDuration
delay:kRFPVictorySequenceStateVoteDelay
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
if (winnerIsDem) {
[_currentStateImageView setFrame:CGRectMake(-_currentStateImageView.frame.size.width,
_currentStateImageView.frame.origin.y,
_currentStateImageView.frame.size.width,
_currentStateImageView.frame.size.height)];
}
else {
[_currentStateImageView setFrame:CGRectMake(1024,
_currentStateImageView.frame.origin.y,
_currentStateImageView.frame.size.width,
_currentStateImageView.frame.size.height)];
}
}
completion:^(BOOL finished) {
// Do some stuff
}
];
}
];
}
Gracias por la respuesta, pero esta idea también tiene sus propios problemas. El uso de un 'NSTimer' estándar no sincronizará la animación con la velocidad de visualización del dispositivo, lo que puede hacer que la animación se vea entrecortada. Sería mejor usar un 'CADisplayLink' que es similar pero diseñado exactamente con el propósito de sincronizar con la pantalla. Aún así, el uso de un objeto de enlace de visualización para ejecutar ~ 10 animaciones serializadas podría dar como resultado un código de spaghetti serio. En última instancia, mi pregunta es * ¿por qué * pausar las animaciones en un árbol de capas afecta los valores de retraso para * posteriores * animaciones? Parece extraño, ¿no? – Sean
"un código serio de espaguetis" ... sí, tienes razón ... pero después de todo soy italiano;) – Beppe