5

In my macOS application I have menu items, which are replicated also in main UI. Application is consisted of main window with its delegate and single view along with its view controller. In app delegate I capture menu item click action, then I need to send this event to my view controller in order to take appropriate actions and also update main UI.

Question is how to access my view controller (NSViewController) from app delegate?

Pablo
  • 28,133
  • 34
  • 125
  • 215
  • "In app delegate I capture menu item click action, then I need to send this event to my view controller in order to take appropriate actions and also update main UI." It doesn't sound like a good game plan. – El Tomato Sep 08 '18 at 22:28
  • Now I capture menu item action in controller, then update menu items via app delegate. Does it sound better? – Pablo Sep 09 '18 at 12:25
  • No. When you make a pointer to a view controller in AppDelegate, AppDelegate will only have information on that view controller at the time when the application is launched. Your best choice is to set First Responders through Interface Builder. – El Tomato Sep 09 '18 at 12:56
  • That's how I do - connecting menu item action to view controller in IB. – Pablo Sep 09 '18 at 13:02

2 Answers2

2

If you have window as an IBOutlet you can do

var rootViewController: MyViewController? {
    return window!.contentViewController as? MyViewController
}

func sendPressed(_ sender: Any?) {
   rootViewController?.sendPressed()
}

If you don‘t have a window variable you can get it through

NSApplication.shared.orderedWindows.first!
Fabian
  • 5,040
  • 2
  • 23
  • 35
0

Actually you don't need a reference to the controller. There is First Responder

  • Declare the IBActions
  • In Interface Builder connect the menu items to the First Responder (red cube) of the target object and choose the appropriate action.

The action will be executed in the first object of the responder chain which implements the action.

vadian
  • 274,689
  • 30
  • 353
  • 361
  • The reason I put menu handling in app delegate is that I need to change the state of `NSMenuItem` and have mutual exclusive check box for a group of items, so I have reference outlets for each menu item. Now if I declare `IBAction` for menu items in ViewControllers I should tell app delegate to change the state of menu items, using reference outlets or perhaps obtain menu items in View Controller somehow, right? – Pablo Sep 08 '18 at 13:49
  • As for responder chain I have one question. By connecting `IBAction` to menu item action, does the framework still walk through responder chain? I thought `IBAction` is pointing to exact instance and method as target/action, that is created from storyboard. So the link is there after build. As far as I know untargeted actions are walking through responder chain. It's probably worth to open new question, but since in your answer you mentioned responder chain, I would like to see your feedback on it. – Pablo Sep 08 '18 at 14:02