Держите оба дочерних контроллера NSSplitViewController в цепочке первого респондента

У меня есть приложение на основе документов с NSSplitViewController в качестве контроллера представления содержимого главного окна. Левая панель содержит пользовательский вид с контроллером, который реализует некоторые команды меню.

Правая панель содержит стандартный NSTableView с контроллером. Когда приложение запускает команды меню, работают должным образом, но как только в правой части таблицы выбрано что-либо, команды меню отключаются.

Как я могу убедиться, что контроллер представления левой панели остается внутри первой цепочки респондента?

Я попытался подключить команды меню непосредственно к правильному контроллеру представления, но IB не разрешает соединения с другой сценой в раскадровке. Я могу подключиться только к объектам в той же сцене.

С Уважением,

Ремко Поэлстра

2 ответа

Решение

Подключитесь к первому ответчику.

Вы можете сделать так, чтобы все дочерние контроллеры представления реагировали на действия, реализуя -[NSResponder дополнительная часть TargetForAction:sender:] в вашем подклассе NSSplitViewController:

- (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;
}

В 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)
}
Другие вопросы по тегам