我在主应用程序菜单中有一个菜单项,我想将其操作路由到视图控制器(NSViewController
)。接口层次结构如下所示:NSWindowController
有一个主应用程序窗口控制器。在窗口内部有一个拆分视图,拆分视图中的右视图由NSViewController
控制。
Window + NSWindowController
`-- NSSplitView
`-- NSView
`-- NSView + NSViewController
菜单项连接到Interface Builder中的First Responder。有问题的视图控制器实现了适当的方法,但菜单项保持禁用状态。当我将方法移动到NSWindowController
时,菜单项会启用。
我想我需要将视图控制器连接到响应器链,因此我将其设置为窗口控制器的nextResponder
;没有雪茄。我做错了什么?
答案 0 :(得分: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;
}
这是一个很多代码,但它是一个通用的解决方案,可以使控制器代码免于ad-hoc转发。希望这不是太多魔术。
答案 1 :(得分:2)
您可以将窗口控制器设置为窗口的委托,以便它现在将成为响应程序链的一部分。
假设您拥有自己的NSWindowController
子类,则可以在那里捕获菜单事件并在控制器中调用适当的方法。
不幸的是,文档建议不要在各个视图和子视图之间的响应器链中插入任何内容,这样你就不能只在那里挤压你的视图控制器。
更多here,但我认为你已经咨询过了。