我在主应用程序菜单中有一个菜单项,我想将其操作路由到视图控制器(NSViewController
)。界面层次结构如下:有一个NSWindowController
的主应用程序窗口控制器。窗口内有一个拆分视图,拆分视图中的右视图由NSViewController
控制。
Window + NSWindowController
`-- NSSplitView
`-- NSView
`-- NSView + NSViewController
菜单项连接到界面生成器中的第一个响应程序。有问题的视图控制器实现了适当的方法,但菜单项保持禁用状态。当我将方法移动到NSWindowController
时,菜单项将被启用。
我想我需要将视图控制器连接到响应器链,所以我将其设置为窗口控制器的nextResponder
;没有雪茄。我做错了什么?
最后,我为窗口控制器添加了一个基类,并将调用转发到"子"控制器:
- (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;
}
这是大量的代码,但它是一个通用的解决方案,可以使控制器代码免受自组织转发。希望它不会太神奇。
您可以将窗口控制器设置为窗口的委托,这样它现在将成为响应程序链的一部分。
假设您有自己的NSWindowController
子类,那么您可以简单地在那里捕获菜单事件,并在控制器中调用适当的方法。
不幸的是,文档建议不要试图在各种视图和子视图之间的响应器链中插入任何内容,所以你不能只是把视图控制器挤在那里。
这里有更多,但我认为你已经咨询过了。