I have a NSTextField inside of a NSTableCellView, and I want an event which informs me when my NSTextField has got the focus for disabling several buttons, I found this method:
-(void)controlTextDidBeginEditing:(NSNotification *)obj{
NSTextField *textField = (NSTextField *)[obj object];
if (textField != _nombreDelPaqueteTextField) {
[_nuevaCuentaActivoButton setEnabled:FALSE];
[_nuevaCuentaPasivoButton setEnabled:FALSE];
[_nuevaCuentaIngresosButton setEnabled:FALSE];
[_nuevaCuentaEgresosButton setEnabled:FALSE];
}
}
but it triggers just when my textfield is begin editing as this says, I want the buttons disabled when I get the focus on the textField, not when I already started to type
EDIT: Gonna put my code based on the help received by Joshua Nozzi, it still doesn't work
MyNSTextField.h
#import <Cocoa/Cocoa.h>
@class MyNSTextField;
@protocol MyNSTextFieldDelegate
@optional -(BOOL)textFieldDidResignFirstResponder:(NSTextField *)sender;
@optional -(BOOL)textFieldDidBecomeFirstResponder:(NSTextField *)sender;
@end
@interface MyNSTextField : NSTextField
@property (strong, nonatomic) id <MyNSTextFieldDelegate> cellView;
@end
MyNSTextField.m
#import "MyNSTextField.h"
@implementation MyNSTextField
- (BOOL)becomeFirstResponder
{
BOOL status = [super becomeFirstResponder];
if (status)
[self.cellView textFieldDidBecomeFirstResponder:self];
return status;
}
- (BOOL)resignFirstResponder
{
BOOL status = [super resignFirstResponder];
if (status)
[self.cellView textFieldDidResignFirstResponder:self];
return status;
}
@end
on my viewcontroller EdicionDeCuentasWC.m
#import "MyNSTextField.h"
@interface EdicionDeCuentasWC ()<NSTableViewDataSource, NSTableViewDelegate, NSControlTextEditingDelegate, NSPopoverDelegate, MyNSTextFieldDelegate>
@end
@implementation EdicionDeCuentasWC
#pragma mark MyNSTextFieldDelegate
-(BOOL)textFieldDidBecomeFirstResponder:(NSTextField *)sender{
NSLog(@"textFieldDidBecomeFirstResponder");
return TRUE;
}
-(BOOL)textFieldDidResignFirstResponder:(NSTextField *)sender{
NSLog(@"textFieldDidResignFirstResponder");
return TRUE;
}
#pragma mark --
@end
it's important to say in visual editor, already changed all my NSTextFields to MyNSTextField class and set delegate to my File's Owner (EdicionDeCuentasWC)
I think I nailed it. I was trying subclassing
NSTextFiled
to overridebecomeFirstResponder()
andresignFirstResponder()
, but once I click it,becomeFirstResponder()
gets called andresignFirstResponder()
gets called right after that. Huh? But search field looks like still under editing and focus is still on it.I figured out that, when you clicked on search field, search field become first responder once, but
NSText
will be prepared sometime somewhere later, and the focus will be moved to theNSText
.I found out that when
NSText
is prepared, it is set toself.currentEditor()
. The problem is that whenbecomeFirstResponder()
's call,self.currentEditor()
hasn't set yet. SobecomeFirstResponder()
is not the method to detect it's focus.On the other hand, when focus is moved to
NSText
, text field'sresignFirstResponder()
is called, and you know what?self.currentEditor()
has set. So, this is the moment to tell it's delegate that that text field got focused.Then next, how to detect when search field lost it's focus. Again, it's about
NSText
. Then you need to listen toNSText
delegate's methods liketextDidEndEditing()
, and make sure you let it's super class to handle the method and see ifself.currentEditor()
is nullified. If it is the case,NSText
lost it's focus and tell text field's delegate about it.I provide a code, actually
NSSearchField
subclass to do the same thing. And the same principle should work forNSTextField
as well.You will need to change
NSSerachField
toZSearchField
, and your client class must conform toZSearchFieldDelegate
notNSTextFieldDelegate
. Here is a example. When user clicked on search field, it extend it's width and when you click on the other place, search field lost it's focus and shrink its width, by changing the value ofNSLayoutConstraint
set by Interface Builder.It might depend on the behavior of the OS, I tried on El Capitan 10.11.4, and it worked.
The code can be copied from Gist as well. https://gist.github.com/codelynx/aa7a41f5fd8069a3cfa2
I found the following code on the macrumors forums.
It seems to work.
I have a custom
NSTextField
subclass that overrides-becomeFirstResponder
and-resignFirstResponder
. Its-cellView
property requires conformance to a protocol that declares-textDidBecome/ResignFirstResponder:(NSTextField *)sender
but it's enough to give you the general idea. It can easily be modified to post notifications for which your controller can register as an observer. I hope this helps.