textDidChange vs controlTextDidChange - objective-c

Can someone explain me why textDidChange isn't handling my delegate but controlTextDidChange works from NSTextField.
- (void)controlTextDidChange:(NSNotification *)aNotification{
NSBeep();
}
from
- (void)textDidChange:(NSNotification *)aNotification{
NSBeep();
}

controlTextDidChange: is the correct delegate method defined on NSTextField (inherited from NSControl).
textDidChange: is a method that, when called on NSTextField, makes it behave as if its text changed (including calling the above method). It is not a delegate method for you to implement.
It's a little inconsistent of Apple as they do have a textDidChange: delegate method on UISearchBarDelegate.

textDidChange: Informs the delegate that the text object has changed its characters or formatting attributes.
I'm guessing that means its font (text attributes) changes, and not the text inputted.

Related

NSTextField Subclass textDidEndEditing: Deleting Text

I have an NSTextFeild Subclass in which I would like to implement textDidEndEditing: to check after each edit if it is empty or not. The method is being called perfectly, but when I click into another NSTextField (or a subclass), all the text that was in the first textfield is immediately deleted. If I click out into the view, the text stays, but is deleted the next time i click into another textfeild. All I have in the method right now is an NSLog. Does anyone have any ideas as to why this could be happening?
#import "BufferTableCellViewTextField.h"
#implementation BufferTableCellViewTextField
- (void)textDidEndEditing:(NSNotification *)notification{
NSLog(#"END");
}
#end
You need to call -super:
- (void)textDidEndEditing:(NSNotification *)notification;
{
[super textDidEndEditing:notification];
NSLog(#"END");
}
This delegate method wouldn't be causing your problem. I'd look back to your subclass and check to see that you are not using any UITextField delegate methods that are expecting a YES response that you may have inadvertently changed the return responses for. It may be helpful to post you subclass so we can see what is going on in there too...

How to overwrite textDidChange: method correctly?

I subclassed NSTextField and overwrite the textDidChange: as:
- (void)textDidChange:(NSNotification *)notification
{
// ... My own operation
}
But when I drag a input text box into my .xib file and control drag another class to assign the delegate I found the delegate's controlTextDidChange: method was never called.
Now tryingto solve this problem, I tried two ways al below:
I. calling super:
- (void)textDidChange:(NSNotification *)notification
{
// ... My own operation
[super textDidChange:notification];
}
But I got an error in runtime: attempt to insert nil object from objects[0]
II. calling delegate's method
- (void)textDidChange:(NSNotification *)notification
{
// ... My own operation
if ([self.delegate responseToSelector:#selector(controlTextDidChange:)])
{
[self.delegate ...]; // <--- Opps, something not happerned here.
}
}
What not happerned? I expected that the auto-complete should display the controlTextDidChange: method at the position of ... above. But it did not, actually. I typed the method directly, compilation fail because method not found.
How should I make my sub-class call the delegate normally? How should I overwrite the textDidChange: method correctly?
Further question for Vytautas:
I am sure I was using NSTextField. And I set a break point inside controlTextDidChange: method. As it was called, I should have known.
I did control-drag the text field to the delegate object, and I print delegate object in the textDidChange: method, it was sure that the delegate was set correctly.
The other delegate methods, such as controlTextDidBeginEditing: were called correctly. But controlTextDidChange: not called
I tried comment out the over-written in the subclassed NSTextField class, then controlTextDidChange: was called.
Therefore I was quite sure that I am not overwritting the textDidChange: right. But I do not known how to fix it.
What made me confused mostly was that why auto-completion did not show the controlTextDidChange: method when I attempted to call it.
About the auto-completion, here is how it showed:
No - controlTextDidChange: method.
2nd further reply for Vytautas:
I tried calling '[self controlTextDidChange]' but it did not work, and error occurred (as highlighted below):
I can say that - controlTextDidChange: is called for sure.
Maybe there is something wrong with you bindings in your *.xib.
Also it can be that in *.xib you are using NSTextView, not NSTextField.
In this case - controlTextDidChange: won't be called for sure.
If that is the case then you should take a look to NSTextView, NSTextViewDelegate and NSTextDelegate. NSTextView delegate has an alternative method for this - textDidChange:

UITableView reloadData causes UITextField to resignFirstResponder

I have a textField that is set to change the tableView's dataSource with each letter that's entered (and call reloadData).
But for some reason, every time a letter is entered, the keyboard is dismissed.
Anyone know why?
Your text field is resigning because reloaded cells are sent a -resignFirstResponder message due to the fact that their survival is not guaranteed after a reload. See this related question for more.
Use this method textFieldShouldReturn: and add UITextFieldDelegate delegate in yourClass.h file. set delegate to yourTextfield and write following code in viewDidLoad method.
yourTextfield.delegate = self;
and also implement the textFieldShouldReturn: as following as
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
[theTextField resignFirstResponder];
return YES;
}
I think it will be helpful to you.

NSTextFieldCell Delegate?

I have a text field cell in a table view, from which I need to be made aware when it ends editing. I thought I would set my Controller class as the text field cell's delegate, and then use NSTextField's delegate method textDidEndEditing:, but realized that the text field cell doesn't seem to have delegate methods? Why is this, and what can I do (other than subclassing) to be informed when editing is finished?
Thanks
NSTextFieldCell inherits from NSCell (well, technically from NSActionCell which inherits from NSCell). The NSCell class is used to (from the docs):
The NSCell class provides a mechanism for displaying text or images in an NSView object without the overhead of a full NSView subclass.
Notably, The cell class is used for "displaying text or images", and not dealing with interaction with the user. Similarly, with the NSTextField class:
The NSTextField class uses the NSTextFieldCell class to implement its user interface.
The NSTextField deals with the actual user input, whilst using the text field cell to simply implement its user interface, and similarly, the delegate methods to provide notification when the editing of text has ended is provided through the NSTextField class and not through the NSTextFieldCell class.
If you want to be notified of when editing ends in an NSTableView, then you need to register yourself as an observer of the NSTextDidEndEditingNotification (you might want to read the NSNotificationCenter class reference if you are unfamiliar with notifications). To do this, place the following in your controller class; the awakeFromNib function is a good place to include it to ensure that it is called upon your application's startup:
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:#selector(textDidEndEditing:)
name:NSTextDidEndEditingNotification
object:tableView];
Where tableView is the pointer to your NSTableView object. Then, simply implement the method as follows:
- (void)textDidEndEditing:(NSNotification *)aNotification
{
// Do what you want here
}
Don't forget to remove yourself as an observer upon deallocation:
- (void)dealloc
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self];
}
The reason that you set the object that you are observing to be the NSTableView instance (and not the cell itself) is that under the hood, when you edit a cell in the table, the cell that you are dealing with isn't being edited directly; it is the window's (or a custom) field editor. When editing ends, the field editor then passes the new value for that cell on to the table view. However the table view will post a notification to say that a cell has finished being edited.
Implement the tableView:setObjectValue:forTableColumn:row: method in the NSTableViewDataSource protocol. Put it next to the tableView:objectValueForTableColumn:row: method that you've already implemented.
- (void)tableView:(NSTableView *)aTableView
setObjectValue:(id)anObject
forTableColumn:(NSTableColumn *)aTableColumn
row:(NSInteger)rowIndex
{
[mutableArrayWithStrings replaceObjectAtIndex:rowIndex withObject:anObject];
}

Delegate methods of NSTextField using NSNotification

I have an NSTokenField in a window. I am using it to store tags related to a Core Data object. Right now I have it set up such that I can add tags to the objects, but I cannot delete them. I need a delegate method on the NSTokenField that can let me know when the user has moved the focus out of the NSTokenField. Since NSTokenField is a subclass of NSTextField I figured that I could use its delegate methods. It has two that I think could be useful:
- (void)textDidChange:(NSNotification *)aNotification
- (void)textDidEndEditing:(NSNotification *)aNotification
I set my controller class as the delegate of my NSTokenField and put both of these methods into my controller class. I put a basic NSLog into each of them and neither is triggered when I interact with the NSTokenField. I am guessing it has something to do with NSNotification. How do I activate these methods?
The NSTokenField invokes the controlTextDidChange: and the controlTextDidEndEditing: notifications; change the two methods above, implementing them as:
- (void)controlTextDidChange:(NSNotification*)aNotification
{
//Code here..
}
- (void)controlTextDidEndEditing:(NSNotification *)aNotification
{
//Code here..
}