I wrote some animation code in OS X 10.6, but the animations aren't working properly when I recompile the app for 10.9.
I've got an array of buttons, for each of them my goal is to have it shrink, then return to normal size, then shrink, and then return to normal size (to "flex" a couple of times).
NSMutableArray *animations = [NSMutableArray arrayWithCapacity:buttons.count];
NSMutableArray *allAnimations = [NSMutableArray arrayWithCapacity:buttons.count*4];
for(NSButton *button in buttons) {
// store the original frame and generate the smaller frame
NSRect originalFrame = button.frame;
NSRect smallFrame = [self smallRectForRect:originalFrame scale:0.9];
// build dictionaries which describe the animations from normal-to-small and vice versa
NSMutableDictionary *normalToSmall = [NSMutableDictionary dictionary];
[normalToSmall setObject:button forKey:NSViewAnimationTargetKey];
[normalToSmall setObject:[NSValue valueWithRect:originalFrame] forKey:NSViewAnimationStartFrameKey];
[normalToSmall setObject:[NSValue valueWithRect:smallFrame] forKey:NSViewAnimationEndFrameKey];
NSMutableDictionary *smallToNormal = [NSMutableDictionary dictionary];
[smallToNormal setObject:button forKey:NSViewAnimationTargetKey];
[smallToNormal setObject:[NSValue valueWithRect:smallFrame] forKey:NSViewAnimationStartFrameKey];
[smallToNormal setObject:[NSValue valueWithRect:originalFrame] forKey:NSViewAnimationEndFrameKey];
// create, and chain together, the shrink, reset, shrink, reset animation chain
NSViewAnimation *animation1 = [self createAnimationWithDictionary:normalToSmall duration:duration startingAfterAnimation:nil];
NSViewAnimation *animation2 = [self createAnimationWithDictionary:smallToNormal duration:duration startingAfterAnimation:animation1];
NSViewAnimation *animation3 = [self createAnimationWithDictionary:normalToSmall duration:duration startingAfterAnimation:animation2];
NSViewAnimation *animation4 = [self createAnimationWithDictionary:smallToNormal duration:duration startingAfterAnimation:animation3];
// store all of the animations in an array just in case ARC wants to release them prematurely.
[allAnimations addObjectsFromArray:@[animation1, animation2, animation3, animation4]];
// Store the first animation, so that we can start each of the chains after we're done creating them.
[animations addObject:animation1];
}
// start the first animation in each chain
for (NSViewAnimation *animation in animations) {
[animation startAnimation];
}
Here is my function used to create each of the animations:
- (NSViewAnimation*) createAnimationWithDictionary:(NSDictionary*)animationDictionary duration:(float)duration startingAfterAnimation:(NSViewAnimation*)previousAnimation {
NSViewAnimation *animation = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObject:animationDictionary]];
[animation setDuration:duration];
[animation setDelegate:self];
if (previousAnimation != nil) {
[animation startWhenAnimation:previousAnimation reachesProgress:1.0];
}
return animation;
}
I set my window controller as the delegate so I could watch the animations start and end and it appears that only the first animation in each chain starts and ends. The subsequent animations which were configured to -startWhenAnimation:reachesProgress:1.0
do not appear to start at all.
Why won't the subsequent animations start running?