Discussion:
Why are the simplest things the hardest?
Rick Mann
2018-07-05 02:08:02 UTC
Permalink
I'm writing a new macOS app. I started with the document-based app template (no core data). I have a custom window controller, and a hierarchy of custom NSViewControllers embedded in a split view controller (I even subclassed the split view controller).

I have a simple IBAction method that logs a debugging message, and I try to send that action from a menu item to the first responder. I want to implement that method in one of my view controllers, but it never seems to get called. I've tried adding the method to every view controller, the window controller, and the app delegate, but it never gets called. However, if I connect the menu item to the app delegate, it gets called.

What am I doing wrong?

Thanks.
--
Rick Mann
***@latencyzero.com


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkive.net
Ken Thomases
2018-07-05 03:40:29 UTC
Permalink
Post by Rick Mann
I'm writing a new macOS app. I started with the document-based app template (no core data). I have a custom window controller, and a hierarchy of custom NSViewControllers embedded in a split view controller (I even subclassed the split view controller).
I have a simple IBAction method that logs a debugging message, and I try to send that action from a menu item to the first responder. I want to implement that method in one of my view controllers, but it never seems to get called. I've tried adding the method to every view controller, the window controller, and the app delegate, but it never gets called. However, if I connect the menu item to the app delegate, it gets called.
What am I doing wrong?
Is one of your views actually the first responder? Does the window have key or main status? By default, it wouldn't be able to become key or main if it doesn't have a title bar and isn't resizable. Is there a view that accepts first responder (has overridden -acceptsFirstResponder to return YES)? (Of course, certain standard controls like NSTextField accept first responder without you having to subclass them.)

I assume you're running macOS 10.10 or newer. If not, you would have to take special steps to include those controllers in the responder.

Regards,
Ken

_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkive.net
Rick Mann
2018-07-05 03:45:32 UTC
Permalink
Post by Ken Thomases
Post by Rick Mann
I'm writing a new macOS app. I started with the document-based app template (no core data). I have a custom window controller, and a hierarchy of custom NSViewControllers embedded in a split view controller (I even subclassed the split view controller).
I have a simple IBAction method that logs a debugging message, and I try to send that action from a menu item to the first responder. I want to implement that method in one of my view controllers, but it never seems to get called. I've tried adding the method to every view controller, the window controller, and the app delegate, but it never gets called. However, if I connect the menu item to the app delegate, it gets called.
What am I doing wrong?
Is one of your views actually the first responder? Does the window have key or main status? By default, it wouldn't be able to become key or main if it doesn't have a title bar and isn't resizable. Is there a view that accepts first responder (has overridden -acceptsFirstResponder to return YES)? (Of course, certain standard controls like NSTextField accept first responder without you having to subclass them.)
I've overridden -acceptsFirstResponder to return true on the window controller and view controllers. I don't have any custom views in the window yet, just an SCNView and a slider.

This begins to touch on another issue I'm not satisfied with: if I have multiple NSViewControllers (say, in a split view), and I want them all to respond to (different) menu commands, there seems to be no way to do that directly, by sending command to the first responder, right?
Post by Ken Thomases
I assume you're running macOS 10.10 or newer. If not, you would have to take special steps to include those controllers in the responder.
Yes, 10.13.5
Post by Ken Thomases
Regards,
Ken
--
Rick Mann
***@latencyzero.com


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkive.net
Ken Thomases
2018-07-05 04:31:21 UTC
Permalink
Post by Rick Mann
I've overridden -acceptsFirstResponder to return true on the window controller and view controllers.
That doesn't do anything. -acceptsFirstResponder is a view method and is only called on views, not controllers.
Post by Rick Mann
I don't have any custom views in the window yet, just an SCNView and a slider.
I don't know if SCNView accepts first responder by default. You may need to use a subclass that overrides -acceptsFirstResponder.

A slider would only accept first responder if System Preferences > Keyboard > Shortcuts > Full Keyboard Access is set to All Controls.
Post by Rick Mann
This begins to touch on another issue I'm not satisfied with: if I have multiple NSViewControllers (say, in a split view), and I want them all to respond to (different) menu commands, there seems to be no way to do that directly, by sending command to the first responder, right?
Correct. That's not an appropriate case for targeting the action at the first responder. You would either target the views directly or implement the action methods in a superview or its controller and have that dispatch things from there. You could implement some general scheme that searches the descendant views for one which responds and send it there. Or perhaps have the descendant views register their interest in a specific action method with the controller.

Regards,
Ken

_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkive.net
Rick Mann
2018-07-05 04:44:30 UTC
Permalink
Post by Ken Thomases
Post by Rick Mann
I've overridden -acceptsFirstResponder to return true on the window controller and view controllers.
That doesn't do anything. -acceptsFirstResponder is a view method and is only called on views, not controllers.
Well, it's an NSResponder var, so I assumed any of them could become first responder. Seems perfectly reasonable to choose the deepest appropriate NSResponder, even if it's not a view.
Post by Ken Thomases
Post by Rick Mann
I don't have any custom views in the window yet, just an SCNView and a slider.
I don't know if SCNView accepts first responder by default. You may need to use a subclass that overrides -acceptsFirstResponder.
A slider would only accept first responder if System Preferences > Keyboard > Shortcuts > Full Keyboard Access is set to All Controls.
Post by Rick Mann
This begins to touch on another issue I'm not satisfied with: if I have multiple NSViewControllers (say, in a split view), and I want them all to respond to (different) menu commands, there seems to be no way to do that directly, by sending command to the first responder, right?
Correct. That's not an appropriate case for targeting the action at the first responder. You would either target the views directly or implement the action methods in a superview or its controller and have that dispatch things from there. You could implement some general scheme that searches the descendant views for one which responds and send it there. Or perhaps have the descendant views register their interest in a specific action method with the controller.
Okay, I'll have to do that, thanks.

Annoying I have to have a first responder view just to allow even my Document to respond to menu commands.
Post by Ken Thomases
Regards,
Ken
Thanks!
--
Rick Mann
***@latencyzero.com


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkive.net
Rick Mann
2018-07-07 04:55:03 UTC
Permalink
Post by Rick Mann
Annoying I have to have a first responder view just to allow even my Document to respond to menu commands.
1. The main window’s first responder and the successive responder objects up the view hierarchy
2. The main window itself
3. The window's NSWindowController object (which inherits from NSResponder)
4. The main window’s delegate.
5. The NSDocument object (if different from the main window’s delegate)
6. The application object, NSApp
7. The application object's delegate
8. The application's document controller (an NSDocumentController object, which does not inherit from NSResponder)
As you can see, both the window’s delegate, application object’s delegate, and the `NSDocument` instance itself, is part of the responder chain, which is where you would implement your menu item actions.
Implementing action methods in the view hierarchy should only be used for view-specific actions such as `copy:` and `paste:` (which would depend on the first responder, i.e. ⌘C does different things depending on which view is the first responder, but e.g. ⌘S should always go to the document’s `saveDocument:` action).
If I have view commands (like fixed perspectives in a 3D view) in a menu, I should be able to implement those on the view controller, don't you think?
_______________________________________________
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
https://lists.apple.com/mailman/options/cocoa-dev/rmann%40latencyzero.com
--
Rick Mann
***@latencyzero.com


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This em
Richard Charles
2018-07-07 23:50:32 UTC
Permalink
Post by Rick Mann
If I have view commands (like fixed perspectives in a 3D view) in a menu, I should be able to implement those on the view controller, don't you think?
It depends if the view controller is in the responder chain for the object in question.

The documentation indicates that in macOS 10.10 and later, a view controller does participate in the responder chain.

Cocoa Design Patterns by Buck and Yacktman, Chapter 18 Responder Chain, The Extended Responder Chain page 223 is a great read on the subject. I can’t find my book right now but I think they have sample code that will walk the responder chain, log this to the console, and you can then see exactly what your responder chain looks like. I find this to be a great debugging tool.

--Richard Charles

_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This ema

Rick Mann
2018-07-05 04:59:57 UTC
Permalink
Post by Ken Thomases
Post by Rick Mann
I've overridden -acceptsFirstResponder to return true on the window controller and view controllers.
That doesn't do anything. -acceptsFirstResponder is a view method and is only called on views, not controllers.
Post by Rick Mann
I don't have any custom views in the window yet, just an SCNView and a slider.
I don't know if SCNView accepts first responder by default. You may need to use a subclass that overrides -acceptsFirstResponder.
Hmm, I tried this. It doesn't seem to make anything in my responder chain respond. I tried calling becomeFirstResponder() on it when the view controller loaded. Doesn't seem to have any effect.

Dropping an NSTextView randomly into my window did enable my responder chain.
Post by Ken Thomases
A slider would only accept first responder if System Preferences > Keyboard > Shortcuts > Full Keyboard Access is set to All Controls.
Post by Rick Mann
This begins to touch on another issue I'm not satisfied with: if I have multiple NSViewControllers (say, in a split view), and I want them all to respond to (different) menu commands, there seems to be no way to do that directly, by sending command to the first responder, right?
Correct. That's not an appropriate case for targeting the action at the first responder. You would either target the views directly or implement the action methods in a superview or its controller and have that dispatch things from there. You could implement some general scheme that searches the descendant views for one which responds and send it there. Or perhaps have the descendant views register their interest in a specific action method with the controller.
Regards,
Ken
--
Rick Mann
***@latencyzero.com


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkive.net
Rick Mann
2018-07-05 05:14:42 UTC
Permalink
Weird. Examining the firstResponder shows it is, in fact, my SCNView subclass. Yet menu actions to the first responder don't propagate up.
Post by Ken Thomases
Post by Rick Mann
I've overridden -acceptsFirstResponder to return true on the window controller and view controllers.
That doesn't do anything. -acceptsFirstResponder is a view method and is only called on views, not controllers.
Post by Rick Mann
I don't have any custom views in the window yet, just an SCNView and a slider.
I don't know if SCNView accepts first responder by default. You may need to use a subclass that overrides -acceptsFirstResponder.
A slider would only accept first responder if System Preferences > Keyboard > Shortcuts > Full Keyboard Access is set to All Controls.
Post by Rick Mann
This begins to touch on another issue I'm not satisfied with: if I have multiple NSViewControllers (say, in a split view), and I want them all to respond to (different) menu commands, there seems to be no way to do that directly, by sending command to the first responder, right?
Correct. That's not an appropriate case for targeting the action at the first responder. You would either target the views directly or implement the action methods in a superview or its controller and have that dispatch things from there. You could implement some general scheme that searches the descendant views for one which responds and send it there. Or perhaps have the descendant views register their interest in a specific action method with the controller.
Regards,
Ken
--
Rick Mann
***@latencyzero.com


_______________________________________________

Cocoa-dev mailing list (Cocoa-***@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/gegs%40ml-in.narkive.net

This email sent to ***@ml-in.narkive.net
Loading...