I have a UIView whose layer has 2 sublayers, one is CAShapeLayer and the other is CALayer.
A path using bezierPathWithOvalInRect is set in CAShapeLayer and animated using CABasicAnimation. The "strokeEnd" property is animated from 0.0 to 1.0 for a certain duration. This leads to the fact that the oval draw begins from beginning to end over the duration.
CALayer simply has its content set on the pencil image and animated using CAKeyframeAnimation. The "position" property is animated by setting the path property for CAKeyframeAnimation to the same path as CAShapeLayer, and the same duration as CABasicAnimation. This leads to the pencil moving along the same path for the same duration, and it looks like the pencil is drawing an oval.
Works great in iOS6. However, in iOS7, time is turned off - position animation and strokeEnd are not synchronized - they are synchronized at certain points, in particular, by time 0, duration / 4, duration / 2, duration * 3/4 and duration - but between them sync is disabled.
If instead of an ellipse I use a rectangle or triangle, for example, it works fine in iOS6 and iOS7. Only problem is the ellipse in iOS7.
Essentially, I need to know how to sync 2 different animations, where each animation is an animation of a different layer.
Here is the code that creates 2 layers:
self.drawingLayer = [CAShapeLayer layer];
self.drawingLayer.frame = self.view.bounds;
self.drawingLayer.bounds = drawingRect;
self.drawingLayer.path = path.CGPath;
self.drawingLayer.strokeColor = [[UIColor blackColor] CGColor];
self.drawingLayer.fillColor = nil;
self.drawingLayer.lineWidth = 10.0f;
self.drawingLayer.lineJoin = kCALineJoinRound;
self.drawingLayer.lineCap = kCALineJoinRound;
[self.view.layer addSublayer:self.drawingLayer];
UIImage *pencilImage = [UIImage imageNamed:@"pencil.png"];
self.pencilLayer = [CALayer layer];
self.pencilLayer.contents = (id)pencilImage.CGImage;
self.pencilLayer.contentsScale = [UIScreen mainScreen].scale;
self.pencilLayer.anchorPoint = CGPointMake(0.0, 1.0);
self.pencilLayer.frame = CGRectMake(0.0f, 0.0f, 100.0f, 100.0f);
[self.view.layer addSublayer:self.pencilLayer];
And here is the code that creates and runs two different animations (self.drawingLayer is CAShapeLayer, and self.pencilLayer is CALayer)
CABasicAnimation *drawingAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
drawingAnimation.duration = 10.0;
drawingAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
drawingAnimation.toValue = [NSNumber numberWithFloat:1.0f];
[self.drawingLayer addAnimation:drawingAnimation forKey:@"strokeEnd"];
CAKeyframeAnimation *pencilAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
pencilAnimation.duration = drawingAnimation.duration;
pencilAnimation.path = self.drawingLayer.path;
pencilAnimation.calculationMode = kCAAnimationPaced;
pencilAnimation.delegate = self;
pencilAnimation.fillMode = kCAFillModeForwards;
pencilAnimation.removedOnCompletion = NO;
[self.pencilLayer addAnimation:pencilAnimation forKey:@"position"];
UPDATE
Here is a test application that illustrates the problem.
https://github.com/xjones/AnimatedPaths