I have a CALayer subclass that is constrained to the width of the parent layer, but a fixed height. I want the implicit animation disabled for resizing the window but enabled whenever I set the height of the layer.
To disable the animation when the window is resized I set the layers actions to
NSMutableDictionary *actions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"bounds", [NSNull null], @"position", nil];
and this seems to work. Then I’ve overridden the actionForKey: method in my layer subclass
- (id<CAAction>)actionForKey:(NSString *)event
{
if ([event isEqualToString:@"frame.size.height"]) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"frame.size.height"];
[animation setDuration:0.5f];
return animation;
}
return nil;
}
but then when I change the height of my layer with
[layer setValue:[NSNumber numberForFloat:50.0] forKey:@"frame.size.height"];
the height changes but is not animated. I see the actionForKey: method being called with frame.size.height but no matter what I return it is never animated. The height animates correctly if I don’t set the actions, or have the actionForKey: method, but then the window resizes are also animated, which I don’t want.
Also, maybe I’m misunderstanding, but I thought returning nil from actionForKey: would make the default animations run, but it appears that even the presence of the method stops all implicit animations (whether the actions dictionary is set or not).
What is it am I missing here, I’ll be grateful for any pointers.
Your subclass is going to get
actionForKey:called on it for every key, so if you returnnil, there won’t be an action for that key. If you want the default animations, you should return either[super actionForKey:event]or[CALayer defaultActionForKey:event].A layer’s
frameis calculated from itsboundsandposition, so if there’s no animation for those two, there can’t be an animation forframe.*What you want to do is:
when your layer resizes as a result of the window resizing. This will disable animation just this time (for this transaction); when you change the layer’s size directly, it will still animate. I’m not sure what the correct spot to do that call is; I just tried doing it in a callback from notification that the window was resizing, but that didn’t work. I’m sure it won’t be too hard for you to figure out where to put it in your code.
*: In fact, the docs say: