【问题标题】:Why NSAnimationContext completionHandler does not work (sometimes)?为什么 NSAnimationContext completionHandler 不起作用(有时)?
【发布时间】:2014-11-11 11:00:46
【问题描述】:

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

我在这里错过了什么?

【问题讨论】:

    标签: objective-c completionhandler nsanimationcontext


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      查看completionHandler的文档:

      如果设置为非零值,则保证在所有随后添加到当前 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];
      

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-26
          • 2012-09-08
          • 2016-04-10
          • 2012-09-27
          • 2013-09-10
          • 1970-01-01
          • 2023-03-06
          • 2015-09-12
          相关资源
          最近更新 更多