On Sep 1, 2015, at 7:12 PM, Quincey Morris < email@hidden> wrote:
On Sep 1, 2015, at 11:21 , Alex Hall < email@hidden> wrote:
The procedure for making connections to IBOutlets or IBActions seems to work perfectly when I use it to hook up NSButton, NSTextField, or NSTable controls. When I do the exact same thing for NSMenuItems, though, nothing happens.
As a matter of process, you’re not doing anything wrong, but I don’t believe what you’re trying to is possible. I admit to being a hazy on details here, because there’s a constantly shifting background of Xcode behavioral and UI changes, arising from the introductions of storyboards to the Mac UI paradigm.
In brief, you cannot make outlet or action links between scenes in a storyboard. This is likely a consequence of the fact that a storyboard is implemented as (among other things) a collection of nib files, and there isn’t any way of connecting between nib files, barring some special cases (e.g. via File’s Owner, and of course the First Responder fiction).
This makes sense, in a way, because a menu item is global, but a view controller (and hence any actions it defines) is in the active responder chain only sometimes — it’s not a globally valid destination.
Okay, that makes sense, and I hadn't thought of it that way. In some ways, iOS is easier. :)
For actions, I think you have two choices. One is to put the action method in the app delegate. Since this is part of the application scene, you can link a menu item to its actions, using the storyboard in IB. Or, link your menu item to First Responder within its own scene. (That is to say, leave it with a nil target.) That allows a run time determination to be made whether anything that responds to the action is in the responder chain at the time the menu item is used.
Indeed, connecting to an outlet defined in appDelegate.swift worked perfectly. I'm not clear on the second option--the First Responder? I see it in the outline, but if the menu items have a nil target, how would I then use them to do anything?
Using appDelegate works, as I said, but it feels weird to split my UI code between that file and my view controller. I get why I have to, and I know that on OS X, it's more acceptable to put UI code in that file instead of a dedicated view controller, but the setup seems awkward. For instance, one of my menu items sets focus to an edit field, so the user can press the menu item's hotkey and start typing. The outlet for that field is, of course, in my view controller. With the menu item's action now in my appDelegate file, I'm stuck. I'll probably move all my actions and outlets to the appDelegate (assuming that works), leaving my view controller with little to do. As I said, this isn't a show-stopping problem, it's just odd to pull view controlling code *out* of my view controller and put it somewhere else.
The same thing is true of the opposite direction. You can link outlets from (say) the app delegate to a menu item, because the app delegate is in the same storyboard scene as the menu item. If you really want an outlet from a view controller to a menu item, then you’ll have to add an outlet from the app delegate to the menu item, and make this a public property that the view controller can use. (It’s fairly rare to need to do this, though, since you can usually do whatever you want to the menu item at menu validation time, which is an override method in the view controller.)
|