How do you move a CALayer instantly (without animation)
Solution 1
You want to wrap your call in the following:
[CATransaction begin];
[CATransaction setValue: (id) kCFBooleanTrue forKey: kCATransactionDisableActions];
layer.position = CGPointMake(x, y);
[CATransaction commit];
Solution 2
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
}
Solution 3
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.
Solution 4
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];
Solution 5
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
}
Related videos on Youtube
user
Updated on May 25, 2021Comments
-
user almost 3 years
I need to show two
<div>
s next to each other and with different backgrounds.Unfortunately, the
background-color
of the second<div>
is ignored. I have read some posts and people suggest to addclear:both;
. Unfortunately, it doesn't help. Is there any way how to get abackground-color
for.div2
?CSS:
.div1 { margin-top:10px; float:left; background:blue; width:382px; padding:0 5px 10px 10px; } .div2 { margin-top:10px; width:374px; background:red; padding:0 10px 10px 0; } .clear { clear:both; }
HTML:
<div class="div1">DIV1</div> <div class="div2">DIV2</div> <div class="clear"></div>
-
Fattie over 4 yearsregarding this extremely old QA, the critical issue today is this: stackoverflow.com/a/56980329/294884
-
-
Yogev Shelly over 12 yearsImportant, this effects all CALayer so you want to reenable actions after you're done, i.e [CATransaction setDisableActions:YES]
-
Biclops about 12 yearsDamn I should have said that. Good save. The command disables animations until it is set to NO or until the core graphics animation engine has completed a run cycle. Not sure if that's the right word for it :/ But Thank you for clearing that up for everybody.
-
Mr. T about 11 yearsEasy to remember, easy to understand when you're re-reading the code, and easier to type. Thanks!
-
Fogmeister almost 10 yearsYup, 6 and a half years later. Still helpful. :D
-
k06a over 9 yearsiOS7 supports new shorthand:
[UIView performWithoutAnimation:<#^(void)actionsWithoutAnimation#>];
-
Hector Matos about 9 years7 and a half years later, Still helpful.
-
kanobius almost 8 years7 years, 7 months, and 17 days later: still helpful. Thanks!
-
Andrew almost 8 yearsIt's useful to add the
@noescape
attribute to the block to allow (and make it clear) thatself
is not needed in the block -
0xNSHuman about 7 yearsthumb up 9 years later
-
vilanovi over 6 yearsYes!! thumbs up 9 years later!
-
Fattie over 4 yearsguys @vilanovi etc, 12 years later it's wrong :) these days, you do this: stackoverflow.com/a/56980329/294884