I have a menu item inside the main app menu and I’d like to route its action to a view controller (NSViewController
). The interface hierarchy looks like this: There’s a main app window controller by an NSWindowController
. Inside the window there’s a split view, and the right view in the split view is controlled by the NSViewController
.
Window + NSWindowController
`-- NSSplitView
`-- NSView
`-- NSView + NSViewController
The menu item is connected to First Responder in the Interface Builder. The view controller in question implements the appropriate method, but the menu item stays disabled. When I move the method to the NSWindowController
, the menu item gets enabled.
I figured I need to get the view controller to the responder chain, so I set it as the nextResponder
for the window controller; no cigar. What am I doing wrong?
In the end I added a base class for my window controllers and made it forward calls to the “child” controllers:
- (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;
}
It’s a lot of code, but it’s a general solution that keeps the controller code free from ad-hoc forwarding. Hopefully it’s not too much magic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With