Animate custom CALayer properties inside a CATransaction
Until now I've been able to animate the custom properties of my CALayer subclass, 开发者_如何学Pythonthanks to + (BOOL)needsDisplayForKey:(NSString *)key
and CABasicAnimations
.
However it turns out that chaining animations can become very tricky because all the code takes place in a single animationDidStop:finished:
method.
So I wanted to switch to CATransactions
since they support the new block syntax, which would allow me to specify a completion block with + (void)setCompletionBlock:(void (^)(void))block
.
But it appears to me that CATransaction
can only animate the so-called 'animatable properties' and it doesn't work with my custom layer properties, even with the needsDisplayForKey:
method implemented.
So is there a way to make custom properties in a CALayer
to animate with CATransaction
?
EDIT: My intent is to do something along the lines:
[CATransaction begin];
[CATransaction setAnimationDuration:0.5];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[CATransaction setCompletionBlock:^{
NSLog(@"blabla");
}];
myLayer.myProperty = newValue;
[CATransaction commit];
The update of myProperty value to newValue
is not animated. I've tried to implement
actionForLayer:forKey:
in the view managing myLayer to return a CABasicAnimation
. But actionForLayer:forKey:
is never called with the key myProperty
. And yes, myLayer
is not view.layer
but a sublayer, and yes I set the delegate of myLayer
to the containing view.
I believe, based on my reading of some source code, that you can still use a CABasicAnimation
within the CATransaction
. Any CAAnimations
added between the [CATransaction begin]
and [CATransaction commit]
should be a part of the transaction.
[CATransaction begin];
[CATransaction setAnimationDuration:0.5];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[CATransaction setCompletionBlock:^{
NSLog(@"blabla");
}];
// Create the CABasicAnimation using your existing code
CABasicAnimation *myPropertyAnim = [CABasicAnimation animationWithKeyPath:@"myProperty"];
// TODO: Setup animation range
myPropertyAnim.toValue = newValue;
// The CATransaction does not observe arbitrary properties so this fails:
//myLayer.myProperty = newValue;
// Add the CAAnimation subclass during the CATransaction
[myLayer addAnimation:myPropertyAnim forKey:@"myKey"];
[CATransaction commit];
Apologies that I don't have a project setup to easily test this now, but I believe it will work.
Check these site for the code:
- http://www.mentalfaculty.com/mentalfaculty/Blog/Entries/2010/9/22_FLIPPIN_OUT_AT_NSVIEW.html
- http://boondoggle.atomicwang.org/lemurflip/MFFlipController.m
Code that I referenced:
[CATransaction begin];
[topLayer addAnimation:topAnimation forKey:@"flip"];
[bottomLayer addAnimation:bottomAnimation forKey:@"flip"];
[CATransaction commit];
There's a great class called CAAnimationBlocks, and explained here, that is a category on CAAnimation that allows you to use completion blocks like you would on a UIView.
You use it simply by calling:
CABasicAnimation myAnimation;
[myAnimation setCompletion:^(BOOL finished) { // Do something }];
精彩评论