Enabled NSTableView refuses to resign first responder and eats all the events sent to first responder - macos

I have an NSTableView and it eats all events sent to the first responder. Before adding table view, everything was perfect, and all the messages sent to the first responder were sent correctly to my NSDocument subclass.
As soos as I added table view, it insists on always having focus. The focus indicator around it never disappears unless an external sheet view controller (or something similar) gains focus. When table view has focus, my messages sent to the first responder doesn't work with keyboard shortcuts. They work when I click them from the menu bar by pointer though.
If I set "refuses first responder" it doesn't change anything. If I set "enabled" to false, then my app returns to normal behavior (though I obviously can't interact with the table view).
How can I prevent table view's "always focused" behavior. I've tried In a view-based NSTableView, how make a control the first responder with a single click?'s answer but didn't change anything.

Since I've subclassed NSTableView, I've overridden becomeFirstResponder and returned NO without doing anything, and it worked great! I can interact with the table view freely, it just doesn't gain focus.

Related

NSTableView allow selection change without becoming first responder

I've a window with a split view. Left is a NSTableView, to the right a custom view.
When my custom view is active in a 'command mode' I need it to remain first responder status so it can receive a cancelOperation: event when the escape key is pressed. But I do want the user to be able to change the selection in the table view.
Unfortunately, as long as my custom view refuses to resign first responder status the table view doesn't respond.
How can I make sure that the table view allows changing the selection without becoming first responder? Or how can I make sure the cancelOperation: event is delivered to my custom view, while it's not first responder?
the table view allows changing the selection without becoming first responder
Don't do this. It will confuse the user. The table view should become first responder.
Or how can I make sure the cancelOperation: event is delivered to my custom view, while it's not first responder
Put Cancel button in the window with key equivalent Escape. Or if you don't want a button, let an object in the responder chain (view controller, window controller) catch the escape key by implementing cancel: and tell the custom view to cancel.

Understanding first responder behavior

From the app delegate, I make a window and set it's contentView to be a view programmatically generated from a plist specification. I then bring the window to front. The window has a toolbar, and when the buttons on the toolbar are pressed, it is supposed to display a different contentView.
I have found that the first content view appears with its topmost text field subview already selected as first responder, but changing the view from the toolbar (it sets contentView on the window) to a different view will not select any of that view's text fields as first responder.
I want to have consistency, so ideally either it would never auto-select a control as first responder or it would always auto-select a control as first responder, but I don't really understand what process is making the control first responder in the first place.
Could somebody please explain what is causing that, so I can either prevent it or try to emulate it when switching views?
hussain Shabbir's answer is on the right track, but misses a few things.
First, setting the window's initial first responder, and then making the same view its first responder, is redundant. The point of the first is to cause the second.
Second, you need to set the window's initial first responder before making the window visible:
Sets a given view as the one that’s made first responder (also called the key view) the first time the window is placed onscreen.
If the window is already visible when you set its initial first responder, nothing will happen.
You need to set the initial first responder before you make the window visible for the first time.
The best place to do that is not in code at all—it's in the nib.
You would then not have either of those lines of code.
Better yet:
The window has a toolbar, and when the buttons on the toolbar are pressed, it is supposed to display a different contentView.
Have you considered using NSTabView? It handles this automatically (every tab view item has its own initial first responder outlet).
If you want when you click on different views your textfield should be become first responder, Then the two lines of code below should work:-
Here on the basis of your condition use these below lines:-
[[self window] setInitialFirstResponder:(NSView *)YourTextFieldName];
[[self window] makeFirstResponder:(NSView *)YourTextFieldName];

`controlTextDidEndEditing` gets fired when TextField becomes first responder

I'm trying to detect when user finishes editing a NSTextField by implementing NSTextFieldDelegate's controlTextDidEndEditing: method. However the problem is that upon initially making the NSTextField first responder of the window, immediately the controlTextDidEndEditing: notification gets fired. I tried this in an extremely simple test app and confirms the result. Would really appreciate some pointers on why this is the case and how to detect when textField loses focus.
As the text field is first Responder, selectText: message will also sent to textField, which will cause it to end editing. If you don't want this behavior set NO to selectable property of textField.
- (void)selectText:(id)sender;
Ends editing and selects the entire contents of the receiver if it’s selectable.

how to catch when the NSTextView in a NSComboBox gets first responder status

I try to do some treatment when a NSComboBox looses first responder status, and hence gets "resignFirstResponder", however my treatment should happen only when the combobox really loose the first responder status, not when the internal NSTextView used to implement the text of the combobox itself gets the first responder status.
Is there an official way to detect that the first responder status went from the NSComboBox to its inner NSTextView?
Can I get a pointer to that NSTextView? and maybe set its delegate?
Regards
In fact, there is no "inner NSTextView", there is one such NSTextView per NSWindow, which gets reparented to the editing control (text, combobox) which needs it at will, this is the so called "field editor". There is a possibility to override it by the way with windowWillReturnFieldEditor in NSWindow delegate.
The actual answer is that we can detect becomeFirstResponder on the combo and then textDidEndEditing.
Reference: "Working With the Field Editor" in "Text editing programming guide" in Apple developer documentation.

Clean way to resign first responder of NSSearchField when done?

In my application I have an NSSearchField that is bound to an arraycontroller which performs searches as the user types.
The problem is that the search field never resigns firstresponder-status once it receives it.
What would be the cleanest way of resigning firstresponder status when the user presses Enter or clicks outside of the search field? If possible I would prefer to do as much work as possible in Interface Builder.
[searchField.window makeFirstResponder:nil]
If you just want to get rid of the focus ring, you can disable it in the NIB.
If you want to resign first responder when the user clicks empty space in the window, you have to use a custom NSView as the window's content view and override mouseDown: to call the above method.

Resources