views:

25

answers:

1

Hi, I have a CALayer A with one sublayer B I want A to be resized (to be shrank) so I add the animations to my layer A but when I commit the animation sublayer B is not shrank. Its size remains(but its position changes as its superlayer bounds changes) How can I make my B layer to be resized along with A animation?

This is what I wrote:

 CABasicAnimation *fadeInAnimation; 
 fadeInAnimation=[CABasicAnimation animationWithKeyPath:@"opacity"];
 fadeInAnimation.repeatCount = 1;
 fadeInAnimation.autoreverses = NO;
 fadeInAnimation.fromValue = [NSNumber numberWithFloat:1.0];
 fadeInAnimation.toValue = [NSNumber numberWithFloat:0.0];

 CABasicAnimation *shrinkAnimation;
 shrinkAnimation = [CABasicAnimation animationWithKeyPath:@"bounds.size"];
 shrinkAnimation.repeatCount = 1;
 shrinkAnimation.autoreverses = NO;
 shrinkAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 
 shrinkAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(0, 0)];

 aniGroupOFF = [[CAAnimationGroup animation] retain];
 aniGroupOFF.delegate = self;
 aniGroupOFF.duration = ANI_DURATION;
 aniGroupOFF.animations = [NSArray arrayWithObjects:shrinkAnimation, fadeInAnimation, nil]; 

And the commit:

[self addAnimation:aniGroupOFF forKey:@"shrinkAndFade"];
self.opacity = 0.0;

Answer:

CABasicAnimation *shrinkAnimation;
    shrinkAnimation = [CABasicAnimation animationWithKeyPath:@"transform"]; //use transform instead of bounds.size
    shrinkAnimation.repeatCount = 1;
    shrinkAnimation.autoreverses = NO;
    shrinkAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 
    shrinkAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DScale(self.transform, 0.1, 0.1, 1.0)];

    aniGroupOFF = [[CAAnimationGroup animation] retain];
    aniGroupOFF.delegate = self;
    aniGroupOFF.duration = ANI_DURATION;
    aniGroupOFF.animations = [NSArray arrayWithObjects:shrinkAnimation, nil]; 
A: 

The easiest way to achieve this is to animate the keyPath "transform.scale" instead of "bounds.size".

If you stick with "bounds.size" you will need to implement layoutSublayers on layer A or layoutSublayersOfLayer:(CALayer*)aLayer on A's delegate and manually adjust B's size in that implementation.

tonklon
Thanks, I will try transform.scale, but one interesting thing: I wrote [layer setNeedsDisplayOnBoundsChange:YES]; and overrode layoutSublayer and tried to adjust bounds/frame of the sublayer but layoutSublayer is only called in initialization. Hence sublayer is not shrunk.
nacho4d
Did you implement layoutSublayers on layer A or B? Should be A. I cannot think why layoutSublayers on A should not be called when it's bounds are animated.
tonklon