Objective c NSAnimationContext结束时如何触发回调?

Objective c NSAnimationContext结束时如何触发回调?,objective-c,cocoa,macos,core-animation,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

我有一个动画,可以移动一些视图。此动画完成后,我希望窗口重新计算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];
此代码的问题是在视图处于新位置之前调用了
RecreacteKeyViewLoop
,这意味着keyviewloop是错误的

我该如何解决这个问题


我的第一个想法是在动画结束后的回调中调用
RecreacteKeyViewLoop
,但我不知道如何执行此操作。

如果使用动画,则这有一个animationDidStop:finished:delegate方法


希望这对您有所帮助。

您应该能够将
-animationForKey:
发送到您的视图,以获取
动画实例,然后将您自己设置为其委托人并实现该方法。

一些不太明显的东西,或者至少对我来说不明显的东西,当您执行
setFrame:
时,有两个动画正在进行,其中键为
frameSize
frameOrigin

根据您的原始帧和最终帧,您可能需要将自己注册为其中一个或两个帧的代理

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

例如

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

查看我的帖子:


我编写了一个类,使用块为您处理这个问题。希望您的目标允许阻塞!:)

如果您正在设置
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

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

[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!");
}];
[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!");
}];