如何让我的应用 expand/collapse from/to 成为 Finder 图标?

How do I make my app expand/collapse from/to a Finder icon?

您知道有时当您关闭 Finder window 或文档时,它会缩小到它在 Finder 中的显示。我希望我的应用程序也能够做到这一点。这个有 API 吗?我找不到。

执行摘要:如果您想要此行为,请使用 NSDocument 系统。

详情:

您似乎在 GIF 中使用了 TextEdit。碰巧,Apple publishes the source code for TextEdit as sample code。所以我们可以看看它是否做了什么特别的事情来实现这一点。

我在 TextEdit 源代码中找不到任何内容。我查了一会儿并设置了一些断点,但没有找到任何证据表明 TextEdit 是“手动”执行此操作的。

我发现如果您使用“文件”>“打开”打开文件(而不是在 Finder 中双击该文件),您不会获得动画关闭window,即使文件在 Finder 中可见。

但是如果您使用“文件”>“打开”打开文件,然后(不关闭 window)在 Finder 中双击该文件,那么您 do 得到动画结束 window.

所以我又四处寻找,设置断点并查看反汇编程序列表,然后我在 -[NSWindow _close] 中找到了我认为重要的部分。它基本上是这样的:

- (void)_close {
    if (!_wFlags.windowDying) { return };
    if (_auxiliaryStorage->_auxWFlags.windowClosed) { return; }

    void (^actuallyCloseMyself)() = ^{ ... code to actually close the window ... };

    NSWindowController *controller = self.windowController;
    if (![controller respondsToSelector:@selector(document)]) { goto noCloser; }
    NSDocument *document = controller.document;
    if (![document respondsToSelector:@selector(fileURL)]) { goto noCloser; }
    QLSeamlessDocumentCloser *closer = [[NSDocumentController _seamlessDocumentCloserClass] seamlessDocumentCloserForURL:document.fileURL];
    if (closer == nil) { goto noCloser; }
    CGRect frame = NSRectZero;
    [closer closeWindow:self contentFrame:&frame withBlock:actuallyCloseMyself];
    goto done;

noCloser:
    actuallyCloseMyself();

done:
    _auxiliaryStorage->_auxWFlags.wantsHideOnDeactivate = YES;
}

所以基本上,如果您的 window 附加到 NSWindowController,并且控制器有 NSDocument,那么 AppKit 将尝试使用QLSeamlessDocumentCloserQL 前缀表示它是 QuickLook 的一部分(class 实际上是在 QuickLookUI 框架中找到的,它是 Quartz 框架的一部分)。

我想发生的事情是,当您在 Finder 中打开文件时,Finder 告诉 QuickLook 系统(可能是 quicklookd 进程)它在屏幕上的哪个位置显示文件的图标。当调用 closer 时(在 TextEdit 中),如果 QuickLook 有一个要关闭的框架,它会在实际关闭 window 之前将 window 向下移动到该框架。如果您没有通过 Finder 打开文件,QuickLook 没有可以设置动画的帧,因此它可能只是立即调用 actuallyCloseMyself 块。