I must be missing something simple, but I can't see it. First, the setup:

  • DATreeView, a subclass of NSView
  • DATreeViewController, a subclass of NSViewController
  • MainMenu.xib has an instance of DATreeViewController, which is configured to load a view from DATreeView.xib
  • MainMenu.xib also has an instance of DendreaAppDelegate, which has a DATreeViewController outlet (which is wired up to MainMenu.xib's DATreeViewController instance.
  • Do Something!, a menu item wired up to send a doSomething: message to the First Responder.
  • Not coincidentally, DATreeViewController has an action called doSomething:.

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!

+2  A: 

Does your view accept and successfully become first responder?

Peter Hosey
Ah! Since the action was in the view controller, that's where I was overriding -acceptsFirstResponder. But the view controller isn't in the view hierarchy! Thanks!

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?

Turns out it was simpler than that. Since the action is in the view controller, that's where I was overriding -acceptsFirstResponder. But Cocoa only looks at the view hierarchy for a responder, and DAView wasn't accepting first responder...