I have a png sprite sheet and corresponding plist file loaded and I'm trying to animate contentsRect property of a CALayer to display a sprite animation from the above mentioned aprite sheet. Here is a code:
CGFloat width = myLayer.frame.size.width;
CGFloat height = myLayer.frame.size.height;
myLayer.bounds = CGRectMake( 0, 0, width, height );
myLayer.contentsGravity = kCAGravityCenter;
myLayer.contents=(id)pImage; // This is my sprite sheet
CAKeyframeAnimation *keyFrameContentsRectAnimation = [CAKeyframeAnimation animationWithKeyPath:@"contentsRect"];
keyFrameContentsRectAnimation.path = pAnimationPath; // This is a path to animate on
keyFrameContentsRectAnimation.values = pRects; // This is an array of normalized CGRects representing sprite sheet
keyFrameContentsRectAnimation.fillMode = kCAFillModeRemoved;
keyFrameContentsRectAnimation.calculationMode = kCAAnimationDiscrete;
keyFrameContentsRectAnimation.duration=pAnimationDuration;
keyFrameContentsRectAnimation.repeatCount = 1;
The above code seems to be working as expected as long as I disable path animation (i.e. comment out path property from keyFrameContentsRectAnimation) - the animation works and contentsRect moves around my sprite sheet.
But here is the problem: all my sprites require some offset within a layer frame in order to get my animation look right(offset varies depending on a transparency crop).
So I figured if I create a path from these offset points that I have and get it into path property of my animation that should resolve the problem. Unfortunately it's not the case... As soon as I add path property, instead of sprites animation I see the whole sprite sheet image for the duration of animation... What did I miss?
Well, after some reading and experimenting I have a working solution... In order to get the sprites show up in the right places I had to add another animation into an animation group and clip CALayer to dimensions of my sprite:
myLayer.bounds = CGRectMake( 0, 0, 256.0, 256.0 ); //my sprite dimentions
myLayer.contentsGravity = kCAGravityCenter;
myLayer.contents=(id)pImage; // This is my sprite sheet
CAKeyframeAnimation *keyFrameContentsRectAnimation = [CAKeyframeAnimation animationWithKeyPath:@"contentsRect"];
keyFrameContentsRectAnimation.values = pRects; // This is an array of normalized CGRects representing sprite sheet
keyFrameContentsRectAnimation.fillMode = kCAFillModeRemoved;
keyFrameContentsRectAnimation.calculationMode = kCAAnimationDiscrete;
keyFrameContentsRectAnimation.duration=pAnimationDuration;
keyFrameContentsRectAnimation.repeatCount = 1;
CAKeyframeAnimation* kfanim = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
kfanim.path = pAnimationPath;
kfanim.values = pRects;
kfanim.fillMode = kCAFillModeBoth;
kfanim.calculationMode = kCAAnimationDiscrete;
kfanim.duration=pAnimationDuration;
kfanim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
NSArray *animations = [NSArray arrayWithObjects:keyFrameContentsRectAnimation,
kfanim, nil];
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
[animationGroup setDuration:pAnimationDuration];
[animationGroup setRepeatCount: 1];
[animationGroup setAnimations:animations];