I'm trying to drag a CALayer in an iOS app.
As soon as I change its position property it tries to animate to the new position and flickers all over the place:
layer.position = CGPointMake(x, y)
How can I move CALayers instantly? I can't seem to get my head around the Core Animation API.
You want to wrap your call in the following:
[CATransaction begin];
[CATransaction setValue: (id) kCFBooleanTrue forKey: kCATransactionDisableActions];
layer.position = CGPointMake(x, y);
[CATransaction commit];
You can also use the convenience function
[CATransaction setDisableActions:YES]
as well.
Note: Be sure to read the comments by Yogev Shelly to understand any gotchas that could occur.
Swift 3 Extension :
extension CALayer {
class func performWithoutAnimation(_ actionsWithoutAnimation: () -> Void){
CATransaction.begin()
CATransaction.setValue(true, forKey: kCATransactionDisableActions)
actionsWithoutAnimation()
CATransaction.commit()
}
}
Usage :
CALayer.performWithoutAnimation(){
someLayer.position = newPosition
}
As others have suggested, you can use CATransaction
.
The problem comes arises because CALayer has a default implicit animation duration of 0.25 seconds.
Thus, an easier (in my opinion) alternative to setDisableActions
is to use setAnimationDuration
with a value of 0.0
.
[CATransaction begin];
[CATransaction setAnimationDuration:0.0];
layer.position = CGPointMake(x, y);
[CATransaction commit];
Combining previous answers here for Swift 4, to clearly make the animation duration explicit...
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
}