0

默认行为:选项键强制使用 Tab

我有一个基于文档的 macOS 应用程序,带有一个自定义的NSDocumentController. 该应用程序可以处理两种类型的文档,每种文档都有自己的窗口和视图。

现在,如果用户关闭了始终在窗口中创建选项卡的选项,cmd-N将始终创建一个新窗口。

如果用户键入cmd-option-N,无论全局或应用程序的选项卡首选项如何,框架都会自动在前窗口内创建一个选项卡。这不需要我进行额外的编程。

到目前为止,一切都很好。

现在,我有一个cmd-shift-N. 由于我的自定义 DocumentController,这每次都会创建一个新窗口,正如预期的那样。

挑战:通过额外的修饰符实现相同的目标

我希望用户能够键入cmd-shift-option-N以在现有文档窗口中创建新选项卡,就像cmd-option-N主文档类型一样。

但是,该框架似乎只处理cmd-option-N用于自动创建选项卡的普通内容。对于其他修饰符组合(如此处,使用 shift),这似乎不起作用:如果我仅为 设置了菜单cmd-shift-N,则按下cmd-shift-option-N只会发出哔声。如果我添加一个明确的菜单cmd-shift-option-N,它会根据需要创建一个新窗口而不是选项卡。

所以我需要模拟将新文档变成选项卡而不是新窗口的行为。我该如何做到这一点,将全局选项卡设置为不创建选项卡?

4

1 回答 1

0

通过反复试验,我想出了以下解决方案。

这需要一个NSDocument子类,我们称之为“CustomDocument”。

在其中,我添加了一个标志来控制是否要将新窗口添加为选项卡:

@interface CustomDocument : NSDocument
   @property BOOL foceIntoTab;
@end

然后我需要实现一个自定义处理程序来创建窗口控制器,我首先确定是否已经有一个窗口可以添加另一个,然后创建新控制器,最后将其添加为选项卡:

- (void)makeWindowControllers // override
{
    __block NSWindow *frontWindow = nil;
    if (self.forceIntoTab) {
        // Find the topmost window that's of my document type
        [NSApp enumerateWindowsWithOptions:NSWindowListOrderedFrontToBack usingBlock:^(NSWindow *window, BOOL *stop) {
            if ([window.windowController.document isKindOfClass:CustomDocument.class]) {
                frontWindow = window;
                *stop = YES;
            }
        }];
    }

    NSWindowController *windowController = [[NSStoryboard storyboardWithName:@"Main" bundle:nil] instantiateControllerWithIdentifier:@"Custom Controller"];

    if (frontWindow) {
        [frontWindow.tabGroup addWindow:windowController.window];
        [windowController.window orderFront:frontWindow];
        [windowController.window makeKeyWindow];
    }

    NSViewController *viewController = windowController.contentViewController;
    [viewController setRepresentedObject:self];
    [self addWindowController:windowController];
}

剩下的就是forceIntoTab通过菜单栏创建新窗口时的设置。例如,我可以在我的自定义 DocumentController 类中执行此操作:

- (nullable __kindof NSDocument *)makeUntitledDocumentOfType:(NSString *)typeName error:(NSError **)outError // override
{
    CustomDocument *doc = [super makeUntitledDocumentOfType:typeName error:outError];
    doc.forceIntoTab = YES;
    return doc;
}
于 2021-05-20T12:59:07.363 回答