Search code examples
objective-ccore-animation

Multiple CALayers Animation - Fill Mode


I am separating the screen into small tiles, then animating each tile to perform a transition:

    for (int x=0; x<number_of_x_splits; x++) {

    for (int y=0; y<number_of_y_splits; y++) {

        CGSize splitSize = CGSizeMake(screenBounds.width / number_of_x_splits, screenBounds.height / number_of_y_splits);

        CATransformLayer *transformLayer = [CATransformLayer layer];
        [transformLayer setFrame:CGRectMake(splitSize.width * x, splitSize.height * y, splitSize.width, splitSize.height)];
        [transformLayer setPosition:CGPointMake((splitSize.width * x) + splitSize.width / 2, (splitSize.height * y) + splitSize.height / 2)];

        ... adding some sublayers to transformLayer...

        CABasicAnimation *rotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
        [rotate setDuration:5.0];
        [rotate setFromValue:[NSNumber numberWithFloat:0]];
        [rotate setToValue:[NSNumber numberWithFloat:M_PI]];
        [rotate setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
        [rotate setTimeOffset:(1 / (number_of_x_splits + number_of_y_splits)) * (x+y)];
        [rotate setFillMode:kCAFillModeForwards];
        [rotate setRemovedOnCompletion:NO];
        [transformLayer addAnimation:rotate forKey:@"transform.rotation.y"];

    }
}

The problem is that only the last CALayer in the chain remains at final position. I have also tried to set the CALayer final transform value:

[transformLayer setTransform:CATransform3DMakeRotation(M_PI, 0, 1, 0)];

I guess it have to do with creating another instance of CALayer in the loop reset the properties of the previous layer.

Anyone have a suggestion how to remedy the situation?


Solution

  • timeOffset is not the property you want to use, that actually changes at what point into the animation it will begin and not the delay until it starts. Instead you should set the beginTime of the animation.

    Remember that the begin time should be CACurrentMediaTime() + yourDelay


    The difference between timeOffset and beginTime can be illustrated like this. I know I've seen this illustration before, I just couldn't find it.

    Normal animation    | 12345678 |
    Begin time          |     12345678 |
    Time offset         | 5678     |