I'm working on a component that is supposed to render several images and animate their position while changing also the contents. I've been inspired by this post: http://ronnqvi.st/controlling-animation-timing/ and thought of using speed to control the animations.
My ideia is to add the CALayers with the animations to a top-level layer whose speed is 0 and then set this layer's speed to 1.0 when it's time to animate.
Here's the code for it:
...
@property (nonatomic,strong) CALayer *animationLayer;
...
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.animationLayer = [CALayer layer];
self.animationLayer.frame = frame;
self.animationLayer.speed = 0.0;
[self.layer addSublayer:self.animationLayer];
}
return self;
}
- (void)addLayerData:(LayerData*)layerData
{
CALayer *aLayer = [CALayer layer];
aLayer.contents = (id) layerData.image.CGImage;
aLayer.frame = CGRectMake(0,0,96,96);
aLayer.position = layerData.position;
aLayer.name = layerData.name;
CGRect pathLayerFrame = layerData.path.bounds;
pathLayerFrame.origin.x = 0.0;
pathLayerFrame.origin.y = 0.0;
CAShapeLayer *pathLayer = [CAShapeLayer layer];
pathLayer.frame = pathLayerFrame;
pathLayer.path = layerData.path.CGPath;
pathLayer.strokeColor = layerData.strokeColor.CGColor;
pathLayer.fillColor = [UIColor clearColor].CGColor;
pathLayer.lineWidth = 10;
pathLayer.lineCap = kCALineCapRound;
[self.animationLayer addSublayer:pathLayer];
CAKeyframeAnimation *positionAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
[positionAnimation setPath: layerData.path.CGPath];
[positionAnimation setDuration: 10.0];
[positionAnimation setRemovedOnCompletion: NO];
[positionAnimation setFillMode: kCAFillModeBoth];
[positionAnimation setKeyTimes:layerData.keyTimes];
CAKeyframeAnimation *contentsAnimation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
[contentsAnimation setValues:[self buildContentImagesFromLayerData:layerData];
[contentsAnimation setCalculationMode:kCAAnimationDiscrete];
contentsAnimation.calculationMode = kCAAnimationLinear;
[contentsAnimation setDuration:0.1];
[contentsAnimation setDelegate:self];
[contentsAnimation setAutoreverses:YES];
[contentsAnimation setRepeatCount:HUGE_VALF];
[contentsAnimation setRemovedOnCompletion:NO];
[contentsAnimation setFillMode:kCAFillModeBoth];
[aLayer addAnimation:positionAnimation forKey:kPostionAnimationKey];
[aLayer addAnimation:contentsAnimation forKey:kContentsAnimationKey];
[self.animationLayer addSublayer:aLayer];
}
- (void)animate
{
self.animationLayer.speed = 1.0;
}
My issue is that although the animationLayer contains all the layers to animate and these have all the animations correctly defined I can't seem to get the layers moving around the screen.
The addLayerData is called several times by external client code, at different times (that is when user taps a button to add an image). The animate is called after that when the user taps a button.
Maybe I've missed something in the article.
Can anyone help me out on this one?
Thanks in advance.
UPDATE
If I drop the animationLayer and add the layers to be animated directly on the view's layer (self.layer) it works correctly.