2008-10-22 12 views
58

Estoy intentando arrastrar un CALayer en una aplicación iOS.Cómo mueves un CALayer al instante (sin animación)

Tan pronto como cambie su posición de propiedad que trata de animar a la nueva posición y parpadea todo el lugar:

layer.position = CGPointMake(x, y) 

¿Cómo se mueven CALayers al instante? Parece que no puedo entender la API Core Animation.

Respuesta

131

desea ceñir su llamada en el siguiente:

[CATransaction begin]; 
[CATransaction setValue: (id) kCFBooleanTrue forKey: kCATransactionDisableActions]; 
layer.position = CGPointMake(x, y); 
[CATransaction commit]; 
+1

eso es exactamente la misma. Ni siquiera pensé en la CATransacción. ¡Muchas gracias! – Mel

+3

2 años después, gracias, lol. – nacho4d

+3

5 años después, ¡gracias! – MichaelScaria

17

También puede utilizar la función de conveniencia

[CATransaction setDisableActions:YES] 

también.

Nota: Asegúrese de leer los comentarios de Yogev Shelly para comprender cualquier problema que pueda ocurrir.

+4

Importante, esto afecta a todos los CALayer, por lo que desea volver a habilitar las acciones una vez que haya terminado, es decir [CATransaction setDisableActions: YES] –

+0

Maldición, debería haber dicho eso. Buen ahorro. El comando desactiva las animaciones hasta que se establece en NO o hasta que el motor de animación de gráficos del núcleo haya completado un ciclo de ejecución. No estoy seguro si esa es la palabra correcta para ello:/Pero gracias por aclarar eso para todos. – Biclops

12

Como han sugerido otros, puede usar CATransaction.
El problema surge porque CALayer tiene una duración de animación implícita predeterminada de 0.25 segundos.

Por lo tanto, una alternativa más fácil (en mi opinión) a setDisableActions es usar setAnimationDuration con un valor de 0.0.

[CATransaction begin]; 
[CATransaction setAnimationDuration:0.0]; 
layer.position = CGPointMake(x, y); 
[CATransaction commit]; 
+0

Fácil de recordar, fácil de entender cuando vuelva a leer el código y más fácil de escribir. ¡Gracias! –

10

Swift 3 Extensión:

extension CALayer { 
    class func performWithoutAnimation(_ actionsWithoutAnimation:() -> Void){ 
     CATransaction.begin() 
     CATransaction.setValue(true, forKey: kCATransactionDisableActions) 
     actionsWithoutAnimation() 
     CATransaction.commit() 
    } 
} 

Uso:

CALayer.performWithoutAnimation(){ 
    someLayer.position = newPosition 
} 
+0

Es útil agregar el atributo '@ noescape' al bloque para permitir (y dejar en claro) que' self' no es necesario en el bloque – Andrew

Cuestiones relacionadas