5
votes

Does anyone now how can I animate multiple layers at the same time using CAKeyframeAnimation ? Each layer has its own CAKeyframeAnimation object. Take a look at the code below:

I have a method that receives an object, creates the CAKeyframeAnimation and attaches the animation to it:

- (void)animateMovingObject:(CALayer*)obj
               fromPosition:(CGPoint)startPosition
                 toPosition:(CGPoint)endPosition
                   duration:(NSTimeInterval)duration {
    CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    pathAnimation.calculationMode = kCAAnimationPaced;
    //pathAnimation.fillMode = kkCAFillModeRemoved; // default 
    //pathAnimation.removedOnCompletion = YES; // default
    pathAnimation.duration = duration;

    // create an empty mutable path
    CGMutablePathRef curvedPath = CGPathCreateMutable();

    // set the starting point of the path
    CGPathMoveToPoint(curvedPath, NULL, startPosition.x, startPosition.y);

    CGPathAddCurveToPoint(curvedPath, NULL, 
                          startPosition.x, endPosition.y, 
                          startPosition.x, endPosition.y,
                          endPosition.x, endPosition.y);
    pathAnimation.path = curvedPath;
    [obj addAnimation:pathAnimation forKey:@"pathAnimation"];
    CGPathRelease(curvedPath);
}

Now, suppose I have 3 layers added as a sublayer in my board game and I make the following calls:

CALayer obj1 = ... // set up layer and add as sublayer
[self animateMovingObject:obj1
             fromPosition:CGPointMake(0.0, 0.0)
               toPosition:CGPointMake(100.0, 100.0)
                 duration:2.0];

CALayer obj2 = ... // set up layer and add as sublayer
[self animateMovingObject:obj2
             fromPosition:CGPointMake(0.0, 0.0)
               toPosition:CGPointMake(150.0, 100.0)
                 duration:2.0];

CALayer obj3 = ... // set up layer and add as sublayer
[self animateMovingObject:obj3
             fromPosition:CGPointMake(0.0, 0.0)
               toPosition:CGPointMake(200.0, 100.0)
                 duration:2.0];

By doing this, I can see only the obj3 being moved from position (0.0, 0.0) to (200.0, 100.0). What am I missing? Should I use NSOperationQueue/Threads? Using the animationDidStart: delegate method of the CAKeyframeAnimation doesn't seem to be useful in this context.

Any ideas?

Thanks in advance.

1

1 Answers

4
votes

If you want to group a series of animations like this, so that they are guaranteed to be synchronized, you could wrap them in a CATransaction:

[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:2.0] forKey:kCATransactionAnimationDuration];     

// Do animations

[CATransaction commit];     

However, I'm not quite sure why the code you've written doesn't fire off the correct animations for each layer, even if they weren't synchronized.

Note that by setting removedOnCompletion to YES, your animation will run and then the object will hop back to its starting point at the end. You probably want that to be NO.