views:

652

answers:

3

I have an animation which moves some views around. When this animation completes I want the window to recalculate the keyview loop. My code is simmilar to the follow mock code:

[NSAnimationContext beginGrouping];        
[newView setAlpha: 0.0]; //hide newView
[self addSubView:newView];

//position the views
[[oldView animator] setFrame: newFrame1];
[[newView animator] setFrame: newFrame2];

[[newView animator] setAlpha: 1.0]; //fade-in newView

[NSAnimationContext endGrouping]; 

[[self window] recalculateKeyViewLoop];

The problem with this code is that recalculateKeyViewLoop is called before the views are in their new positions which means that the keyviewloop is wrong.

How do I fix this?

My first though is to call recalculateKeyViewLoop in a callback from when the animation ends but I can't figure out how to do this.

A: 

if you use CAAnimation this has an animationDidStop:finished: delegate method..

http://developer.apple.com/documentation/GraphicsImaging/Reference/CAAnimation_class/Introduction/Introduction.html#//apple_ref/occ/cl/CAAnimation

Hope this helps

adam
+2  A: 

You should be able to send -animationForKey: to your views to get a CAAnimation instance, then set yourself as its delegate and implement the method that Adam mentioned.

Peter Hosey
+2  A: 

Something that's not so obvious, or at least wasn't to me, is that there are two animations going on when you do a setFrame:, with keys frameSize and frameOrigin.

Depending on what your original and final frames are you may need to register yourself as a delegate for one or both of them.

I'd also recommend that you make a copy of the animation you get back from -animationForKey: and store your modified copy in the animations dictionary of your object. This way your delegate will only be called at the conclusion of that particular objects' animator duration, versus all objects animating that key.

eg.

CAAnimation *animation = [[view animationForKey:@"frameOrigin"] copy];
animation.delegate = self;
[view setAnimations:[NSDictionary dictionaryWithObject:animation forKey:@"frameOrigin"]];

In this way your animation object will supersede the default animation object for that view. Then implement whichever delegate methods you're interested in.

Ashley Clark