To be specific I would like to receive notifications when an NSTextField
gets focus, or when the user clicks on it and is about to start editing.
I've tried the textDidBeginEditing:
method but this is only fired when the user actually starts to type and I need it when the text field becomes the first responder.
I've tried overriding -(BOOL)becomeFirstResponder
but that's only called when the text field first becomes the first responder and not any time after that.
I've tried registering for NSControlDidBeginEditing
notifications but never got any.
Is this possible?
Implement the window's delegate method windowWillReturnFieldEditor:toObject:
. This tells you that the field editor is switching to a different object. Look to see if this object is the text field.
Alternatively, subclass NSWindow and override makeFirstResponder:
. Call super
, look to see what responder is becoming first responder and whether the call to super
returned YES, and return the result of the call to super
.
Just to be clear @matt
's answer put me on the right path; I thought I just ought to clarify exactly how you can do this.
Aim
So I wanted to have an NSTextField
subclass that would know when it became active (i.e. first responder), and then notify it's delegate.
Problem
It turns out the under the hood of OS X text editing is a messy world and you can't really rely on NSTextField
to do it all. Basically when an object that is involved in text editing becomes the first responder, something (the window, the system, the NSApplication
) gives it an _NSKeyboardClipView
(I think it's called that...) as a subview. In turn the _NSKeyboardClipView
has an NSTextView
as a subview, and it's the NSTextView
that becomes the first responder.
Solution
• Subclass (or extend) NSWindow and override the makeFirstResponder:
method.
• Fire a notification using NSNotificationCenter
who's object is the responder object that is passed to the makeFirstResponder:
method.
• Catch the notification in your NSTextField
subclass.
• Here's the horrible bit: you need to check that the notification.object
is, a) a subclass of NSView
and, b) the notification.object.superview.superview == self
(you will have to cast to NSView
here because the object will be of type id
). e.g:
- (void)didBecomeFirstResponder:(NSNotification *)note
{
if ([note.object isKindOfClass:[NSView class]] && [[(NSView *)note.object superview] superview] == self) {
// You just became the first responder
}
}
It's horrible and tacky/hacky but it does work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With