Estoy girando un CALayer e intento detenerlo en su posición final después de completar la animación.
Pero después de que la animación se completa, 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).
alguna sugerencia de cómo lograr esto.
ios
iphone
calayer
cabasicanimation
Nilesh Ukey
fuente
fuente
.presentation()
para obtener el valor "final, visto". Busque las respuestas correctas a continuación que explican que se hace con la capa de presentación.Respuestas:
Aquí está la respuesta, es una combinación de mi respuesta y la de Krishnan.
El valor por defecto es
kCAFillModeRemoved
. (¿Cuál es el comportamiento de reinicio que estás viendo?)fuente
El problema con removeOnCompletion es que el elemento UI no permite la interacción del usuario.
La técnica es establecer el valor FROM en la animación y el valor TO en el objeto. La animación llenará automáticamente el valor TO antes de que comience, y cuando se elimine dejará el objeto en su estado correcto.
fuente
alphaAnimation.beginTime = 1;
,fillMode
¿no es necesario hasta donde puedo decir ...?beginTime
no es relativo, debe utilizar, por ejemplo:CACurrentMediaTime()+1;
fillMode
, vea más en Evitar que las capas vuelvan a los valores originales cuando se usanEstablezca la siguiente propiedad:
fuente
solo ponlo dentro de tu código
fuente
Simplemente puede establecer la clave de
CABasicAnimation
aposition
cuando la agrega a la capa. Al hacer esto, anulará la animación implícita realizada en la posición para el pase actual en el ciclo de ejecución.Puede obtener más información sobre la Sesión de video Apple WWDC 2011 421: Core Animation Essentials (mitad del video)
fuente
someLayer.position = endPosition;
. ¡Y gracias por la referencia al WWDC!Un CALayer tiene una capa 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 finalice la animación, la clave es mantener las dos capas sincronizadas.
Si conoce el valor final, puede configurar el modelo directamente.
Pero si tiene una animación en la que no conoce la posición final (por ejemplo, un desvanecimiento lento que el usuario puede pausar y luego revertir), puede consultar la capa de presentación directamente para encontrar el valor actual y luego actualizar el modelo.
Extraer el valor de la capa de presentación también es particularmente útil para escalar o rotar rutas de teclas. (por ejemplo
transform.scale
,transform.rotation
)fuente
Sin usar el
removedOnCompletion
Puedes probar esta técnica:
fuente
Entonces, mi problema era que estaba tratando de rotar un objeto en un gesto panorámico y tenía múltiples animaciones idénticas en cada movimiento. Tenía ambas
fillMode = kCAFillModeForwards
yisRemovedOnCompletion = false
no me ayudó. En mi caso, tuve que asegurarme de que la clave de animación es diferente cada vez que agrego una nueva animación :fuente
Simplemente configurando
fillMode
yremovedOnCompletion
no funcionó para mí. Resolví el problema estableciendo todas las propiedades a continuación en el objeto CABasicAnimation:Este código se transforma
myView
al 85% de su tamaño (tercera dimensión sin alteraciones).fuente
La animación principal mantiene dos jerarquías de capa: la capa del modelo y la capa de presentación . Cuando la animación está en progreso, la capa del modelo está realmente intacta y mantiene su valor inicial. Por defecto, la animación se elimina una vez que se completa. Luego, la capa de presentación vuelve al valor de la capa del modelo.
Simplemente establecer
removedOnCompletion
enNO
significa que la animación no se eliminará y desperdicia memoria. Además, la capa del modelo y la capa de presentación ya no estarán sincronizadas, lo que puede generar posibles errores.Por lo tanto, sería una mejor solución actualizar la propiedad directamente en la capa del modelo al valor final.
Si hay alguna animación implícita causada por la primera línea del código anterior, intente desactivarla:
fuente
Esto funciona:
La animación principal muestra una 'capa de presentación' sobre su capa normal durante la animación. Por lo tanto, configure la opacidad (o lo que sea) a lo que desea que se vea cuando la animación finalice 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:
Finalmente, si usa 'removeOnCompletion = false', filtrará CAAnimations hasta que la capa finalmente se elimine; evite.
fuente
La respuesta de @Leslie Godwin no es realmente buena, "self.view.layer.opacity = 1;" se realiza de inmediato (toma alrededor de un segundo), por favor arregle alphaAnimation.duration a 10.0, si tiene dudas. Tienes que eliminar esta línea.
Entonces, cuando arreglas fillMode en kCAFillModeForwards y removeOnCompletion en NO, dejas que la animación permanezca en la capa. Si arregla el delegado de animación y prueba algo como:
... la capa se restaura inmediatamente en el momento en que ejecuta esta línea. Es lo que queríamos evitar.
Debe corregir la propiedad de la capa antes de quitarle la animación. Prueba esto:
fuente
Parece que el indicador removeOnCompletion establecido en falso 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 debe hacerse adicionalmente es establecer la propiedad deseada de la capa del modelo de acuerdo con la propiedad de su capa de presentación antes de configurar una nueva animación de esta manera:
fuente
La solución más fácil es usar animaciones implícitas. Esto manejará todos esos problemas para ti:
Si desea personalizar, por ejemplo, la duración, puede usar
NSAnimationContext
:Nota: Esto solo se prueba en macOS.
Inicialmente no vi ninguna animación al hacer esto. El problema es que la capa de una capa respaldada por la vista no se anima de forma implícita. Para resolver esto, asegúrese de agregar una capa usted mismo (antes de configurar la vista con respaldo de capa).
Un ejemplo de cómo hacer esto sería:
El uso
self.wantsLayer
no hizo ninguna diferencia en mis pruebas, pero podría tener algunos efectos secundarios que desconozco.fuente
Aquí hay una muestra del patio de recreo:
false
enisRemovedOnCompletion
: deje que Core Animation se limpie una vez que la animación haya finalizadofuente