On Sep 1, 2015, at 8:12 PM, Alex Hall <[email protected]> wrote:

> On Sep 1, 2015, at 7:12 PM, Quincey Morris 
> <[email protected]> wrote:
>> 
>> 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?

The Cocoa app architecture maintains a concept called the responder chain.  
From any given responder there's a chain of other responders "up" through the 
app architecture, from views to view controllers to superviews and their 
controllers and eventually to the window, the window delegate, the app, and 
then then the app delegate.

There's also the notion of the first responder, which is the responder which 
has keyboard focus.  It's in the key window.

Put those together and you get a responder chain from the first responder.

In a NIB or storyboard, there's a First Responder placeholder.  If you attach 
any target-action connection to an action on that target, then the action is 
sent to the responder chain originating with the first responder.  In reality, 
the First Responder placeholder doesn't actually represent any object.  It 
represents the nil target.  Any control or widget which delivers actions, when 
configured with a nil target, will deliver that action to the first responder 
and the chain up from there.  See -[NSApplication sendAction:to:from:] for the 
specifics.  Also see the Cocoa Event Handling Guide 
<https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/Introduction/Introduction.html>.


> 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.

Does that menu item potentially switch which window is key and/or switch what 
view is showing within it?  If not, if that menu item should only be active 
when the view is already in the responder chain from the first responder, then 
you can target the menu at the First Responder and handle it in your view 
controller.  But that means the menu item will only be able to switch focus 
around within that view.

You could also put it in the window delegate if the menu item should only 
switch focus around within the key window.  That will at least keep it somewhat 
closer to the point of interest.


> I'll probably move all my actions and outlets to the appDelegate (assuming 
> that works), leaving my view controller with little to do.

That probably won't work.  As Quincey said, you won't be able to connect 
outlets across NIB/scenes, either.  So, the app delegate can't have an outlet 
to a text field in your view.

> 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.

Well, if the code needs to change which window is key, which views are 
present/active within that window, and then which control has focus, then it 
isn't really view-controlling code.  It's much more global than that.

You may need to make the action method call into a one-level-deeper controller, 
which will then figure out where to go next.  So, the action method for the 
menu item may target the app delegate.  The app delegate would only know which 
window controller is associated with the action, not which view within it.  So, 
it would call a method on that window controller.  The window controller would 
know which view controller is appropriate, and call into that.  (Or maybe there 
will be a hierarchy of view controllers.)

Regards,
Ken

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/xcode-users/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to