83 votes

Comment déplacer un CALayer instantanément (sans animation) ?

J'essaie de faire glisser un CALayer dans une application iOS.

Dès que je modifie sa propriété de position, il essaie de s'animer à la nouvelle position et clignote dans tous les sens :

 layer.position = CGPointMake(x, y)

Comment déplacer CALayers instantanément ? Je n'arrive pas à comprendre l'API d'animation de base.

0 votes

En ce qui concerne cette AQ très ancienne, la question cruciale aujourd'hui est la suivante : stackoverflow.com/a/56980329/294884

173voto

Ben Gottlieb Points 59900

Vous voulez envelopper votre appel dans ce qui suit :

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

1 votes

C'est exactement cela. Je n'avais même pas pensé à la CATransaction. Je vous remercie de votre attention.

5 votes

Oui, 6 ans et demi plus tard. Toujours utile :D

1 votes

L'iOS7 prend en charge une nouvelle abréviation : [UIView performWithoutAnimation:<#^(void)actionsWithoutAnimation#>];

38voto

CryingHippo Points 3770

Swift 3 Extension :

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

Utilisation :

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

23voto

Biclops Points 412

Vous pouvez également utiliser la fonction de commodité

[CATransaction setDisableActions:YES] 

également.

Note : Assurez-vous de lire les commentaires de Yogev Shelly pour comprendre les problèmes qui pourraient survenir.

5 votes

Important, ceci affecte tous les CALayer, vous devez donc réactiver les actions après avoir terminé, c'est-à-dire [CATransaction setDisableActions:YES].

0 votes

Bon sang, j'aurais dû le dire. Bonne sauvegarde. La commande désactive les animations jusqu'à ce qu'elle soit réglée sur NO ou jusqu'à ce que le moteur d'animation graphique ait terminé un cycle d'exécution. Je ne suis pas sûr que ce soit le bon terme :/ Mais merci d'avoir éclairci ce point pour tout le monde.

15voto

So Over It Points 969

Comme d'autres l'ont suggéré, vous pouvez utiliser CATransaction .
Le problème vient du fait que CALayer a une durée d'animation implicite par défaut de 0,25 seconde.

Ainsi, une alternative plus facile (à mon avis) à la setDisableActions est d'utiliser setAnimationDuration avec une valeur de 0.0 .

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

0 votes

Facile à retenir, facile à comprendre lorsque vous relisez le code, et plus facile à taper. Merci d'avance !

5voto

Giles Points 140

En combinant les réponses précédentes ici pour Swift 4, pour bien expliciter la durée de l'animation...

extension CALayer
{
    class func perform(withDuration duration: Double, actions: () -> Void) {
        CATransaction.begin()
        CATransaction.setAnimationDuration(duration)
        actions()
        CATransaction.commit()
    }
}

Utilisation...

CALayer.perform(withDuration: 0.0) {
            aLayer.frame = aFrame
        }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X