Mac NSTextField won't resign firstResponder

I have a window with some NSTextFields. When I click in one and edit the value and press return, I want the focus to go back to what it was before. I don't want the blue ring around the text field and I don't want further keystrokes going to that text field. I would have thought this would happen automatically.


I tried these, and none of them work


sender.resignFirstResponder()


sender.window?.makeFirstResponder(nil)

InspectorWindowController.window?.makeFirstResponder(nil)


AnotherWindowController.window?.becomeFirstResponder()


I'm doing these at the end of my IBAction associated with the text field. Maybe I have to do it from somewhere else?


Thanks

Accepted Reply

I figured it out. I guess the sent action is happening on another thread. So you have to call makeFirstResponder with Dispatch async:


  DispatchQueue.main.async { //omg
      sender.window?.makeFirstResponder(nil)
  }

Replies

Did you co,nnect both Editing Did End and Exit and Editing Did End even t s to trhe IBAction ?

I don't quite understand what you typed there ... but


I only see Sent Actions in the IB menu, so I connected it to that. The text field is set to have action "Sent on End Editing", so editing is finished when the action is sent.

There are 2 messages that can be sent by the text field (look at connections Inspector in the inspectors panel):

Editing Did End

and

Did End on Exit


They are sent depending you leave by hitting enter, or clicking another field.


I found useful to connect the 2 to the IBAction.

Sorry, I don't see those. Where should they be?


I put two images in this post, but they don't show up when I hit save. Can we not use images in posts?


Anyway these are the options for an NSTextField in the connections inspector:


Triggered Seques

action

Outlets

delegate

formatter

menu

nextKeyView

Sent Actions

action

Accessibility

link

title

Referencing Outlets

positionX (mine)

Received Actions

performClick

print

selectText

takeDoubleValueFrom

takeFloatValueFrom

takeIntegerValueFrom

takeIntValueFrom

takeObjectValueFrom

takeStringValueFrom

Accessibility References

link

title



That's it. Are you sure you aren't talking about iOS?

No, we cannot pst images.


Oh, yes, I thought it was IOS. Sorry for this.


When you call

sender.window?.makeFirstResponder(nil)

do you get true as value ?


let result =  sender.window?.makeFirstResponder(nil)
print(result)

If

responder
isn’t already the first responder, this method first sends a
resignFirstResponder()
message to the object that is the first responder. If that object refuses to resign, it remains the first responder, and this method immediately returns
false
. If the current first responder resigns, this method sends a
becomeFirstResponder()
message to
responder
. If
responder
does not accept first responder status, the
NSWindow
object becomes first responder; in this case, the method returns
true
even if
responder
refuses first responder status.

If

responder
is
nil
, this method still sends
resignFirstResponder()
to the current first responder. If the current first responder refuses to resign, it remains the first responder and this method immediately returns
false
. If the current first responder returns
true
from
resignFirstResponder()
, the window is made its own first responder and this method returns
true
.

I figured it out. I guess the sent action is happening on another thread. So you have to call makeFirstResponder with Dispatch async:


  DispatchQueue.main.async { //omg
      sender.window?.makeFirstResponder(nil)
  }

Yes, like any action involving UI, must take place on main thread.


Most likely, it returned false before ?

No, it still returned true. Surprising there is not more documentation about this -- it's something that must happen all the time when using IB and actions.