CABasicAnimation se restablece al valor inicial una vez completada la animación
Estoy rotando un CALayer y tratando de detenerlo en su posición final después de que se complete la animación.
Pero una vez completada la animación se restablece a su posición inicial.
(los documentos de xcode dicen explícitamente que la animación no actualizará el valor de la propiedad.)
Cualquier sugerencia de cómo lograr esto.
13 answers
Edit : Aquí está la respuesta, es una combinación de mi respuesta y la de Krishnan.
cabasicanimation.fillMode = kCAFillModeForwards;
cabasicanimation.removedOnCompletion = NO;
El valor predeterminado es kCAFillModeRemoved
. (Que es el comportamiento de reinicio que estás viendo.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-25 14:45:32
El problema con removedOnCompletion es que el elemento UI no permite la interacción del usuario.
La técnica I consiste en establecer el valor FROM en la animación y el valor TO en el objeto. La animación llenará automáticamente el valor A antes de que comience, y cuando se elimine dejará el objeto en su estado correcto.
// fade in
CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath: @"opacity"];
alphaAnimation.fillMode = kCAFillModeForwards;
alphaAnimation.fromValue = NUM_FLOAT(0);
self.view.layer.opacity = 1;
[self.view.layer addAnimation: alphaAnimation forKey: @"fade"];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-13 06:04:23
Establezca la siguiente propiedad:
animationObject.removedOnCompletion = NO;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-19 13:07:37
Simplemente póngalo dentro de su código
CAAnimationGroup *theGroup = [CAAnimationGroup animation];
theGroup.fillMode = kCAFillModeForwards;
theGroup.removedOnCompletion = NO;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-27 06:38:21
Simplemente puede establecer la clave de CABasicAnimation
a position
cuando la agregue a la capa. Al hacer esto, anulará la animación implícita realizada en la posición para el pase actual en el bucle de ejecución.
CGFloat yOffset = 30;
CGPoint endPosition = CGPointMake(someLayer.position.x,someLayer.position.y + yOffset);
someLayer.position = endPosition; // Implicit animation for position
CABasicAnimation * animation =[CABasicAnimation animationWithKeyPath:@"position.y"];
animation.fromValue = @(someLayer.position.y);
animation.toValue = @(someLayer.position.y + yOffset);
[someLayer addAnimation:animation forKey:@"position"]; // The explicit animation 'animation' override implicit animation
Puede tener más información sobre la sesión de video de Apple WWDC 2011 421-Core Animation Essentials (en medio del video)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-05 06:28:56
Simplemente configurar fillMode
y removedOnCompletion
no funcionó para mí. Resolví el problema estableciendo todas de las siguientes propiedades en el objeto CABasicAnimation:
CABasicAnimation* ba = [CABasicAnimation animationWithKeyPath:@"transform"];
ba.duration = 0.38f;
ba.fillMode = kCAFillModeForwards;
ba.removedOnCompletion = NO;
ba.autoreverses = NO;
ba.repeatCount = 0;
ba.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.85f, 0.85f, 1.0f)];
[myView.layer addAnimation:ba forKey:nil];
Este código transforma myView
al 85% de su tamaño (3a dimensión inalterada).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-12 20:11:14
@Leslie Godwin la respuesta no es realmente buena, "yo.vista.estrato.opacity = 1; " se hace inmediatamente (tarda alrededor de un segundo), por favor arregle alphaAnimation.duración hasta 10.0, si tienes dudas. Tienes que quitar esta línea.
Por lo tanto, cuando se fija fillMode a kCAFillModeForwards y removedOnCompletion a NO, se deja que la animación permanezca en la capa. Si arreglas el delegado de animación e intentas algo como:
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
[theLayer removeAllAnimations];
}
...la capa se restaura inmediatamente en el momento de ejecutar esta línea. Es lo que queríamos evitar.
Debe corregir la propiedad layer antes de eliminar la animación de la misma. Prueba esto:
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
if([anim isKindOfClass:[CABasicAnimation class] ]) // check, because of the cast
{
CALayer *theLayer = 0;
if(anim==[_b1 animationForKey:@"opacity"])
theLayer = _b1; // I have two layers
else
if(anim==[_b2 animationForKey:@"opacity"])
theLayer = _b2;
if(theLayer)
{
CGFloat toValue = [((CABasicAnimation*)anim).toValue floatValue];
[theLayer setOpacity:toValue];
[theLayer removeAllAnimations];
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-19 15:41:41
Un CALayer tiene una capa de modelo y una capa de presentación. Durante una animación, la capa de presentación se actualiza independientemente del modelo. Cuando se completa la animación, la capa de presentación se actualiza con el valor del modelo. Si desea evitar un salto discordante después de que termine la animación, la clave es mantener las dos capas sincronizadas.
Si conoce el valor final, puede configurar el modelo directamente.
self.view.layer.opacity = 1;
Pero si tienes una animación donde no sabes el final posición (por ejemplo, un fundido lento que el usuario puede pausar y luego revertir), luego puede consultar la capa de presentación directamente para encontrar el valor actual y luego actualizar el modelo.
NSNumber *opacity = [self.layer.presentationLayer valueForKeyPath:@"opacity"];
[self.layer setValue:opacity forKeyPath:@"opacity"];
Extraer el valor de la capa de presentación también es particularmente útil para escalar o girar las rutas de teclado. (e. g.transform.scale
, transform.rotation
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-22 15:03:00
Sin usar el removedOnCompletion
Puedes probar esta técnica:
self.animateOnX(item: shapeLayer)
func animateOnX(item:CAShapeLayer)
{
let endPostion = CGPoint(x: 200, y: 0)
let pathAnimation = CABasicAnimation(keyPath: "position")
//
pathAnimation.duration = 20
pathAnimation.fromValue = CGPoint(x: 0, y: 0)//comment this line and notice the difference
pathAnimation.toValue = endPostion
pathAnimation.fillMode = kCAFillModeBoth
item.position = endPostion//prevent the CABasicAnimation from resetting item's position when the animation finishes
item.add(pathAnimation, forKey: nil)
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-30 10:31:21
Esto funciona:
let animation = CABasicAnimation(keyPath: "opacity")
animation.fromValue = 0
animation.toValue = 1
animation.duration = 0.3
someLayer.opacity = 1 // important, this is the state you want visible after the animation finishes.
someLayer.addAnimation(animation, forKey: "myAnimation")
Core animation muestra una 'capa de presentación' encima de su capa normal durante la animación. Por lo tanto, establezca la opacidad (o lo que sea) a lo que desea ver cuando la animación termine y la capa de presentación desaparezca. Haga esto en la línea antes de agregar la animación para evitar un parpadeo cuando se complete.
Si desea tener un retraso, haga lo siguiente:
let animation = CABasicAnimation(keyPath: "opacity")
animation.fromValue = 0
animation.toValue = 1
animation.duration = 0.3
animation.beginTime = someLayer.convertTime(CACurrentMediaTime(), fromLayer: nil) + 1
animation.fillMode = kCAFillModeBackwards // So the opacity is 0 while the animation waits to start.
someLayer.opacity = 1 // <- important, this is the state you want visible after the animation finishes.
someLayer.addAnimation(animation, forKey: "myAnimation")
Finalmente, si usas 'removedOnCompletion = false' se filtrará CAAnimations hasta que la capa es finalmente dispuesto-evitar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-10 03:11:45
Así que mi problema era que estaba tratando de rotar un objeto en el gesto de panorámica y por lo que tenía múltiples animaciones idénticas en cada movimiento. Tenía ambos fillMode = kCAFillModeForwards
y isRemovedOnCompletion = false
pero no ayudó. En mi caso, Tuve que asegurarme de que la clave de animación es diferente cada vez que agrego una nueva animación :
let angle = // here is my computed angle
let rotate = CABasicAnimation(keyPath: "transform.rotation.z")
rotate.toValue = angle
rotate.duration = 0.1
rotate.isRemovedOnCompletion = false
rotate.fillMode = kCAFillModeForwards
head.layer.add(rotate, forKey: "rotate\(angle)")
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-08 11:21:02
Parece que removedOnCompletion flag establecido en false y fillMode establecido en kCAFillModeForwards tampoco funciona para mí.
Después de aplicar una nueva animación en una capa, un objeto de animación se restablece a su estado inicial y luego se anima desde ese estado. Lo que se debe hacer adicionalmente es establecer la propiedad deseada de la capa de modelo de acuerdo con la propiedad de la capa de presentación antes de establecer una nueva animación como esta:
someLayer.path = ((CAShapeLayer *)[someLayer presentationLayer]).path;
[someLayer addAnimation:someAnimation forKey:@"someAnimation"];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-07 13:23:41
Core animation mantiene dos jerarquías de capas: la capa de modeloy la capa de presentación. Cuando la animación está en progreso, la capa del modelo está realmente intacta y mantiene su valor inicial. De forma predeterminada, la animación se elimina una vez que se completa. A continuación, la capa de presentación vuelve al valor de la capa de modelo.
Simplemente establecer removedOnCompletion
a NO
significa que la animación no se eliminará y desperdiciará memoria. Además, la capa modelo y la presentación la capa ya no será sincrónica, lo que puede conducir a errores potenciales.
Así que sería una mejor solución actualizar la propiedad directamente en la capa del modelo al valor final.
self.view.layer.opacity = 1;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.fromValue = 0;
animation.toValue = 1;
[self.view.layer addAnimation:animation forKey:nil];
Si hay alguna animación implícita causada por la primera línea del código anterior, intente desactivar:
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.view.layer.opacity = 1;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.fromValue = 0;
animation.toValue = 1;
[self.view.layer addAnimation:animation forKey:nil];
[CATransaction commit];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-04 01:15:41