`controlTextDidEndEditing` gets fired when TextField becomes first responder - cocoa

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.

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.

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

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.

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];

Remove Focus from UITextField

I'm trying to remove focus from a UITextField and even though I resign it from being first responder, I'm still not able to have the cursor not focus on the text field.
I don't have any other input on the view to move the focus to and I don't want to create a dummy one either. What is a good workaround for this?
As per the documentation.
To dismiss the keyboard, send the resignFirstResponder message to the text field that is currently the first responder. Doing so causes the text field object to end the current editing session (with the delegate object’s consent) and hide the keyboard.
If you call resignFirstResponder on your textfield then it will end the editing session and the cursor wont be focussing on that textfield.
So please verify one more time whether resignFirstResponder is getting called on that textfield which you want to remove the focus.
Please try to set your current class as delegate of your UITextField. I think you forget to set the delegate that's why it's not working as you are expecting.

Binded NSTextField doesn't update the entity until it lose the focus

I have a Core Data project.
Basically I have an NSTableView where I add some entities (using the "add:" selector), double clicking on the TableView opens a new NSWindow where is possible to edit the entity using some NSTextFields.
Each text field is binded to an attribute of the entity.
Everything is working fine, except the fact that the entity's attributes are updated only when a textfield lose the focus.
If I write on the first text field and then I move to the second one my entry is saved, but if I write on the first text field and I close the window I lose my changes.
How can I update my core data entity as soon as I write something in the text field? Should I use textDidChange:?
--- UPDATE ---
Unfortunately [context save] doesn't work. If I understand correctly the entity is not modified until the NSTextField resign first responder.
The only working solution for now is something like:
(void)controlTextDidChange:(NSNotification *)aNotification
{
NSTextField *tf = [aNotification object];
[self.window makeFirstResponder:tf];
}
but this is quite inelegant, and in any case I also still need to re-set the cursor at the end of the NSTextField.
Setting NSContinuouslyUpdatesValueBindingOption will cause the model to update every time the text field changes, which sets the dirty flag properly and causes the document to save on quit.
I think you could use DidEndEditing or TextDidChange, another way of doing this is handeling in the window close event, but I would not recommend it.
If you don't have one already, you can set a delegate on the window and use -windowWillClose: or observe the NSWindowWillCloseNotification. You can then call [[notification object] makeFirstResponder:[window initialFirstResponder]] to set the window's first responder to its initial first responder as the window is closing. This will cause the control that is first responder (e.g. NSTextField) to resign the first responder status and the binding will save the changes.

Resources