web-dev-qa-db-fra.com

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

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

Dès que je change sa propriété de position, il essaie de s'animer à la nouvelle position et scintille partout:

 layer.position = CGPointMake(x, y)

Comment déplacer instantanément CALayers? Je n'arrive pas à me familiariser avec l'API Core Animation.

74
Mel

Vous souhaitez terminer votre appel comme suit:

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

Extension Swift 3:

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

Utilisation:

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

Vous pouvez également utiliser la fonction confort

[CATransaction setDisableActions:YES] 

ainsi que.

Remarque: assurez-vous de lire les commentaires de Yogev Shelly pour comprendre tous les accrochages qui pourraient survenir.

20
Biclops

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) à setDisableActions est d'utiliser setAnimationDuration avec une valeur de 0.0.

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

Combiner les réponses précédentes ici pour Swift 4, pour rendre clairement explicite la durée de l'animation ...

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

Usage...

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