NSAnimationContext结束时如何触发回调?

时间:2008-12-01 11:57:42

标签: objective-c cocoa macos core-animation

我有一个可以移动一些视图的动画。当这个动画完成时,我希望窗口重新计算keyview循环。我的代码与以下模拟代码类似:

[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];

此代码的问题是在视图处于新位置之前调用recalculateKeyViewLoop,这意味着keyviewloop是错误的。

我该如何解决这个问题?

我的第一个问题是从动画结束时的回调中调用recalculateKeyViewLoop,但我无法弄清楚如何执行此操作。

6 个答案:

答案 0 :(得分:5)

当你使用密钥setFrame:frameSize进行frameOrigin时,有一些不那么明显或至少不适合我的东西是有两个动画。

根据原始帧和最终帧的不同,您可能需要将自己注册为其中一个或两个的委托。

我还建议您复制从-animationForKey:返回的动画,并将修改后的副本存储在对象的animations字典中。这样,只有在特定对象的动画持续时间结束时才会调用您的代理,而不是动画该密钥的所有对象。

例如

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

这样,您的动画对象将取代该视图的默认动画对象。然后实现您感兴趣的任何委托方法。

答案 1 :(得分:4)

您应该能够将-animationForKey:发送到您的观点以获取CAAnimation个实例,然后将自己设置为其委托并实施Adam mentioned的方法。

答案 2 :(得分:1)

如果你使用CAAnimation,它有一个animationDidStop:finished:delegate方法..

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

希望这有帮助

答案 3 :(得分:1)

你可以使用这样的完成处理程序:

[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
    // Start some animations.
    [[myView animator] setFrameSize:newViewSize];
    [[myWindow animator] setFrame:newWindowFrame display:YES];
} completionHandler:^{
    // This block will be invoked when all of the animations started above have completed or been cancelled.
    NSLog(@"All done!");
}];

答案 4 :(得分:0)

在此处查看我的帖子:How would I do this iOS animation on OSX?

我写了一个使用块来为你处理这个问题的类。希望你的目标允许阻止! :)

答案 5 :(得分:0)

如果您要为NSWindow设置动画(而不是NSView),则其他答案将无效,您应该这样做:

CAAnimation *animation = [CABasicAnimation animation];
animation.delegate = self;
self.window.animations = @{@"frame": animation};
[[self.window animator] setFrame:NSMakeRect(0, 0, 400, 200) display:YES];

然后会调用您委托的animationDidStop:finished:方法(在上面的代码中为self