8

我在主应用程序菜单中有一个菜单项,我想将其操作路由到视图控制器 ( NSViewController)。界面层次结构如下所示:有一个主应用程序窗口控制器,由NSWindowController. 窗口内部有一个拆分视图,拆分视图中的右视图由NSViewController.

Window + NSWindowController
    `-- NSSplitView
           `-- NSView
           `-- NSView + NSViewController

菜单项连接到 Interface Builder 中的 First Responder。有问题的视图控制器实现了适当的方法,但菜单项保持禁用状态。当我将方法移至 时NSWindowController,菜单项将启用。

我想我需要将视图控制器获取到响应者链,所以我将它设置nextResponder为窗口控制器;没有雪茄。我究竟做错了什么?

4

2 回答 2

3

最后,我为我的窗口控制器添加了一个基类,并将它的调用转发到“子”控制器:

- (id) childControllerForSelector: (SEL) selector
{
    for (id controller in [childControllers copy])
        if ([controller respondsToSelector:selector])
            return controller;
    return nil;
}

- (BOOL) respondsToSelector: (SEL) selector
{
    return [super respondsToSelector:selector] ? YES :
        [self childControllerForSelector:selector] ? YES :
            NO;
}

- (void) forwardInvocation: (NSInvocation*) invocation
{
    id child = [self childControllerForSelector:[invocation selector]];
    [invocation invokeWithTarget:child];
}

- (NSMethodSignature*) methodSignatureForSelector: (SEL) selector
{
    NSMethodSignature *signature = [super methodSignatureForSelector:selector];
    if (!signature) {
        id child = [self childControllerForSelector:selector];
        signature = [child methodSignatureForSelector:selector];
    }
    return signature;
}

这是很多代码,但它是一种通用的解决方案,可以使控制器代码免于临时转发。希望这不是太多的魔法。

于 2012-07-13T09:49:55.357 回答
2

您可以将窗口控制器设置为窗口的委托,因此它现在将成为响应者链的一部分。

假设您有自己的 子类NSWindowController,那么您可以简单地在那里捕获菜单事件并在控制器中调用适当的方法。

不幸的是,文档建议不要尝试在各种视图和子视图之间的响应者链中插入任何内容,因此您不能只是将视图控制器挤在那里。

更多here,但我认为您已经咨询过。

于 2012-07-12T17:08:48.880 回答