// wc here is an NSWindowController
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0.5f];
if (duplication) {
NSPoint origin = initialSize.origin;
origin.y += initialSize.size.height;
origin = [wc.window cascadeTopLeftFromPoint:origin];
origin.y -= initialSize.size.height;
//[[wc.window animator] setFrameOrigin:origin]; // Why setFrameOrigin and cascadeTopLeftFromPoint are not animated?
initialSize.origin = origin;
[[wc.window animator] setFrame:initialSize display:YES];
}
// This block should be invoked when all of the animations started above have completed or been cancelled.
// For not to show the edit window till the duplication animation not finished
[NSAnimationContext currentContext].completionHandler = ^{
if (edit)
[wc editDocument:self];
else
if (fullScreen)
[wc.window toggleFullScreen:self];
};
[NSAnimationContext endGrouping];在这种情况下,完成块被执行,但不幸的是,它不等待窗口重新定位完成,而是立即打开窗口的编辑工作表,并将它们一起移动。
最奇怪的是,在同一个源文件中,上面几行相同类型的补全块工作得很好:-O
这里我漏掉了什么?
发布于 2016-02-09 20:27:35
这实际上不是一个bug,但它已经让我被绊倒了很多次。您必须在调用任何动画的之前设置完成处理程序。
发布于 2019-05-23 23:09:51
查看completionHandler的文档
如果设置为非nil值,则只要完成或取消了随后添加到当前NSAnimationContext分组的所有动画,就可以保证在主线程上调用上下文的。
完成处理程序只影响在设置完成处理程序之后添加的动画。
最后还说:
如果在当前分组结束之前没有添加动画,或者completionHandler被设置为不同的值,则
将立即调用处理程序。
在您的示例中,在设置完成处理程序和当前分组的末尾之间没有添加动画,因此您的完成处理程序会立即被调用。
正确的代码应该是:
// wc here is an NSWindowController
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0.5f];
// This block should be invoked when all of the animations started above have completed or been cancelled.
// For not to show the edit window till the duplication animation not finished
[NSAnimationContext currentContext].completionHandler = ^{
if (edit)
[wc editDocument:self];
else
if (fullScreen)
[wc.window toggleFullScreen:self];
};
if (duplication) {
NSPoint origin = initialSize.origin;
origin.y += initialSize.size.height;
origin = [wc.window cascadeTopLeftFromPoint:origin];
origin.y -= initialSize.size.height;
//[[wc.window animator] setFrameOrigin:origin]; // Why setFrameOrigin and cascadeTopLeftFromPoint are not animated?
initialSize.origin = origin;
[[wc.window animator] setFrame:initialSize display:YES];
}
[NSAnimationContext endGrouping];发布于 2014-11-11 19:15:33
好的,这是一个BUG,我提交了一份bug报告。下一个版本可以完美地工作
__block NSRect newPosition(initialSize);
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
[context setDuration:0.5f];
if (duplication) {
NSPoint origin = newPosition.origin;
origin.y += newPosition.size.height;
origin = [wc.window cascadeTopLeftFromPoint:origin];
origin.y -= newPosition.size.height;
//[[wc.window animator] setFrameOrigin:origin]; // Why setFrameOrigin and cascadeTopLeftFromPoint are not animated?
newPosition.origin = origin;
[[wc.window animator] setFrame:newPosition display:YES];
}
} completionHandler:^{
// This block will be invoked when all of the animations
// started above have completed or been cancelled.
if (edit)
[wc editDocument:self];
else
if (fullScreen)
[wc.window toggleFullScreen:self];
}];https://stackoverflow.com/questions/26863297
复制相似问题