I have a Mac application (SDK 10.10) with some NSTextFields:
Since I need to get notified when a text field gets and resigns focus, I subclassed NSTextField:
@interface MyTextField : NSTextField
@end
@implementation MyTextField
- (BOOL)becomeFirstResponder
{
BOOL didBecomeFirstResponder = [super becomeFirstResponder];
NSLog(@"%@ didBecomeFirstResponder = %@", [self accessibilityLabel], didBecomeFirstResponder?@"YES":@"NO");
return didBecomeFirstResponder;
}
- (BOOL)resignFirstResponder
{
BOOL didResignFirstResponder = [super resignFirstResponder];
NSLog(@"%@ didResignFirstResponder = %@", [self accessibilityLabel], didResignFirstResponder?@"YES":@"NO");
return didResignFirstResponder;
}
@end
When runing this code and tabbing between the 3 text fields, I get this output in the console:
firstField didResignFirstResponder = YES
firstField didBecomeFirstResponder = YES
secondField didResignFirstResponder = YES
secondField didBecomeFirstResponder = YES
thirdField didResignFirstResponder = YES
thirdField didBecomeFirstResponder = YES
firstField didResignFirstResponder = YES
firstField didBecomeFirstResponder = YES
secondField didResignFirstResponder = YES
secondField didBecomeFirstResponder = YES
Every time I hit the TAB key (or click in one of the inactive text fields), the app outputs
<new first responder> didResignFirstResponder = YES
<new first responder> didBecomeFirstResponder = YES
Shouldn't that be
<old first responder> didResignFirstResponder = YES
<new first responder> didBecomeFirstResponder = YES
???
Do I something terribly wrong here?
The documentation of - (BOOL)resignFirstResponder
says
Notifies the receiver that it’s been asked to relinquish its status as first responder in its window.
So why gets resignFirstResponder
called on the new first responder and not the old one?
I had the same issue and couldn't find a solution, so I ended up with working around it and using
textDidEndEditing()
method for the same purpose. Swift code:MyTextField
subclassesNSTextField
and addsmyDelegate
property to it that should handle logic after the text field lost focus.The protocol itself:
Obviously, instead of using and calling a delegate, you could just implement your lost/gained focus logic right there (e.g. draw different border, etc).
The clue is the
textDidEndEditing()
method and it seems to work for fine when I click in another field, when I press enter or when I tab out.