简体   繁体   English

将NSSplitViewController的子控制器保留在第一响应者链中

[英]Keep both NSSplitViewController's child controllers in first responder chain

I've a document based app with an NSSplitViewController as the main window's content view controller. 我有一个基于文档的应用程序,NSSplitViewController作为主窗口的内容视图控制器。 The left pane contains a custom view with controller, which implements some menu commands. 左窗格包含带控制器的自定义视图,该视图实现了一些菜单命令。

The right pane contains a standard NSTableView with controller. 右侧窗格包含带控制器的标准NSTableView。 When the app starts the menu commands work as expected, but as soon as anything inside the right table view is selected, the menu commands get disabled. 当应用程序启动时,菜单命令按预期工作,但只要选择了右表视图中的任何内容,菜单命令就会被禁用。

How can I make sure that the view controller of the left pane remains inside the first responder chain? 如何确保左窗格的视图控制器保留在第一个响应链中?

I tried hooking up the menu commands directly to the correct view controller, but IB does not allow connections to another scene in a storyboard. 我尝试将菜单命令直接连接到正确的视图控制器,但IB不允许连接到故事板中的另一个场景。 I can only connect to objects in the same scene. 我只能连接到同一场景中的对象。

Regards, 问候,

Remco Poelstra Remco Poelstra

Connect to First Responder. 连接到第一响应者。

You can have all child view controllers respond to actions by implementing -[NSResponder supplementalTargetForAction:sender:] in your NSSplitViewController subclass: 您可以让所有子视图控制器通过在NSSplitViewController子类中实现 - [NSResponder supplementalTargetForAction:sender:]来响应操作:

- (id)supplementalTargetForAction:(SEL)action sender:(id)sender
{
    id target = [super supplementalTargetForAction:action sender:sender];

    if (target != nil) {
        return target;
    }

    for (NSViewController *childViewController in self.childViewControllers) {
        target = [NSApp targetForAction:action to:childViewController from:sender];

        if (![target respondsToSelector:action]) {
            target = [target supplementalTargetForAction:action sender:sender];
        }

        if ([target respondsToSelector:action]) {
            return target;
        }
    }

    return nil;
}

In Swift 4 you can do the following: 在Swift 4中,您可以执行以下操作:

override func supplementalTarget(forAction action: Selector, sender: Any?) -> Any? {
    for childViewController in childViewControllers {
        if childViewController.responds(to: action) {

            return childViewController
        } else {
            guard let supplementalTarget = childViewController.supplementalTarget(forAction: action, sender: sender) else {
                continue
            }

            return supplementalTarget
        }
    }

    return super.supplementalTarget(forAction: action, sender: sender)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM