首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么NSAnimationContext completionHandler不工作(有时)?

为什么NSAnimationContext completionHandler不工作(有时)?
EN

Stack Overflow用户
提问于 2014-11-11 19:00:46
回答 3查看 1.7K关注 0票数 3
代码语言:javascript
复制
    // 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

这里我漏掉了什么?

EN

回答 3

Stack Overflow用户

发布于 2016-02-09 20:27:35

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

票数 6
EN

Stack Overflow用户

发布于 2019-05-23 23:09:51

查看completionHandler的文档

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

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

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

最后还说:

如果在当前分组结束之前没有添加动画,或者completionHandler被设置为不同的值,则

将立即调用处理程序。

在您的示例中,在设置完成处理程序和当前分组的末尾之间没有添加动画,因此您的完成处理程序会立即被调用。

正确的代码应该是:

代码语言:javascript
复制
// 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];
票数 2
EN

Stack Overflow用户

发布于 2014-11-11 19:15:33

好的,这是一个BUG,我提交了一份bug报告。下一个版本可以完美地工作

代码语言:javascript
复制
__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];
}];
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26863297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档