我有一个可以移动一些视图的动画。当这个动画完成时,我希望窗口重新计算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
,但我无法弄清楚如何执行此操作。
答案 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方法..
希望这有帮助
答案 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
)