Handling messages to the first responder in a view controller
-
19-09-2019 - |
Question
I must be missing something simple, but I can't see it. First, the setup:
DATreeView
, a subclass ofNSView
DATreeViewController
, a subclass ofNSViewController
MainMenu.xib
has an instance ofDATreeViewController
, which is configured to load a view fromDATreeView.xib
MainMenu.xib
also has an instance ofDendreaAppDelegate
, which has aDATreeViewController
outlet (which is wired up toMainMenu.xib
'sDATreeViewController
instance.Do Something!
, a menu item wired up to send adoSomething:
message to the First Responder.- Not coincidentally,
DATreeViewController
has an action calleddoSomething:
.
What I want is for the Do Something!
menu item to trigger the doSomething:
action on DATreeViewController
, and let's pretend I can't just set the target/action connection directly. I'll stop right here and ask, is my design totally wrong? Is what I'm trying to do stupid/evil/likely to shame me in the eyes of my God?
No? Great. Now, for the life of me, I can't get the menu item to be active. I'm doing this on Snow Leopard, if that makes any difference.
In order to achieve good integration between NSView
and NSViewController
, e.g. managing the responder chain, I've followed Matt Gallagher's example, with one substantive change: at no point in the NIB loading process does NSView
seem to receive a setViewController:
message, so I send that message myself in DATreeViewController
's loadView
message. From what I can tell, after running the following code in applicationDidFinishLaunching:
NSView *view = self.treeViewController.view;
[self.window.contentView addSubview:view];
the responder chain is set up as expected, that is:
NSWindow < NSView < DATreeViewController < DATreeView
It was my expectation that, being as DATreeViewController
is part of the responder chain, and being as it responds to doSomething:
, and being as it implements no validation, all I would have to do is use Interface Builder to wire the Do Something!
menu item to the First Responder proxy, with doSomething:
as its action, and the menu item would be active automatically.
What am I doing wrong? Thank you all for your invaluable assistance!
Solution
Does your view accept and successfully become first responder?
OTHER TIPS
Is DATreeViewController wired to the DATreeView's viewController outlet in IB?
Have you traced through setViewController: and setNextResponder: to verify that nextResponder is being set up properly?
The responder chain only works for messages in the NSResponder
superclass such as mouseDown
mouseExited
etc. I believe you can do something sneaky by adding a category to NSResponder
to bubble up other methods by looking at the nextResponder
and sending the message up if nextResponder
exists.
This appears to be an example of this technique: https://github.com/MrNoodle/NoodleKit/blob/master/NSResponder-NoodleModalExtensions.m