Ger Teunis
Ger Teunis

Reputation: 955

Core Animation delegate not called

I must be doing something wrong obviously. My delegate doesn't get called when I set the frame of a view.

Frame version NOT working

-(void)someMethod {
    CAAnimation *anim = [CABasicAnimation animation];
    [anim setDelegate:self];
    [[currentViewController view] setAnimations:[NSDictionary dictionaryWithObject:anim forKey:@"frame"]];
    [[newViewController view] setAnimations:[NSDictionary dictionaryWithObject:anim forKey:@"frame"]];

    [[[currentViewController view] animator] setFrame:currentTarget];
    [[[newViewController view] animator] setFrame:newTarget];
}

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag {
    NSLog(@"Yep; works!");
}

Weirdly enough; the same code using alphaValue does work:

-(void)someMethod {
    CAAnimation *anim = [CABasicAnimation animation];
    [anim setDelegate:self];
    [[currentViewController view] setAnimations:[NSDictionary dictionaryWithObject:anim forKey:@"alphaValue"]];
    [[newViewController view] setAnimations:[NSDictionary dictionaryWithObject:anim forKey:@"alphaValue"]];

    [[[currentViewController view] animator] setAlphaValue:0.5];
    [[[newViewController view] animator] setAlphaValue:0.5];
}

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag {
    NSLog(@"Yep; works!");
}

Can you tell me what I am missing here? I just don't understand. Thank you for your time.

Upvotes: 2

Views: 3067

Answers (2)

mrwalker
mrwalker

Reputation: 1903

It is possible to have your delegate method fire using the animator to set your frame. To do this you add animations for frameSize and frameOrigin keys separately:

-(void)someMethod {
    CAAnimation *anim = [CABasicAnimation animation];
    [anim setDelegate:self];

    [[currentViewController view] setAnimations:[NSDictionary dictionaryWithObject:anim forKey:@"frameOrigin"]];
    [[currentViewController view] setAnimations:[NSDictionary dictionaryWithObject:anim forKey:@"frameSize"]];
    [[newViewController view] setAnimations:[NSDictionary dictionaryWithObject:anim forKey:@"frameOrigin"]];
    [[newViewController view] setAnimations:[NSDictionary dictionaryWithObject:anim forKey:@"frameSize"]];

    [NSAnimationContext beginGrouping];
    [[[currentViewController view] animator] setFrame:currentTarget];
    [[[newViewController view] animator] setFrame:newTarget];
    [NSAnimationContext endGrouping];
}

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag {
    NSLog(@"Yep; works!");
}

In this example your delegate method will fire for each of the four animations. If you're repositioning the view without resizing, you don't need the frameSize animations.

Upvotes: 2

Matt Long
Matt Long

Reputation: 24476

You either use the animator or you use an explicit animation. In your case, since you want -animationDidStop to be called, don't use the animator. Also, you shouldn't be trying to animate the frame in an explicit animation. Either animate the bounds or animate the position or you can animate both by adding them both to your view's layer. Change your code to something like this:

-(void)someMethod
{
    CABasicAnimation *boundsAnim = 
                        [CABasicAnimation animationWithKeyPath:@"bounds"];
    [boundsAnim setDelegate:self];
    [boundsAnim setFromValue:[NSValue valueWithRect:currentTarget]];
    [boundsAnim setToValue:[NSValue valueWithRect:newTarget]];

    CABasicAnimation *positionAnim = 
                        [CABasicAnimation animationWithKeyPath:@"position"];
    [positionAnim setDelegate:self];
    [positionAnim setFromValue:[NSValue valueWithPoint:currentPosition]];
    [positionAnim setToValue:[NSValue valueWithRect:newPosition]];

    [[[currentViewController view] layer] addAnimation:boundsAnim forKey:nil];
    [[[currentViewController view] layer] addAnimation:positionAnim forKey:nil];
}

Since this is OSX, you will have to make sure your view's layer is layer backed. You do this by calling:

[[currentViewController view] setWantsLayer:YES];

Upvotes: 1

Related Questions