为什么 NSAnimationContext completeHandler 不起作用(有时)



    // 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

我在这里错过了什么?

这实际上不是一个错误,但它已经绊倒了我很多次。在调用任何动画之前,必须设置完成处理程序。

检查completionHandler的文档:

如果设置为非 nil 值,则保证在随后添加到当前 NSAnimationContext 分组的所有动画完成或取消后立即在主线程上调用上下文的 completionHandler。

来源: https://developer.apple.com/documentation/appkit/nsanimationcontext/1531132-completionhandler?language=objc

完成处理程序

仅影响在设置完成处理程序添加的动画。

最后还说:

如果在当前分组结束之前未添加动画(或者 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];

好的,这是一个错误,我提交了错误报告。下一个版本完美运行

__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];
}];

相关内容

  • 没有找到相关文章

最新更新