I need to know when the user finishes editing a cell in an NSTableView. The table contains all of the user's calendars (obtained from the CalCalendarStore), so in order for the user's changes to be saved I need to inform the CalCalendarStore of the changes. However, I can't find anything that gets called after the user finishes their editing - I would guess that there would be a method in the table's delegate, but I only saw one that gets called when editing starts, not when editing ends.
6 Answers
You can achieve the same result without subclassing NSTableView
by using NSNotificationCenter
or using the NSControl
methods. See the Apple documentation here:
http://developer.apple.com/library/mac/#qa/qa1551/_index.html
It's only a couple of lines of code and worked perfectly for me.
If you can be the delegate
of the NSTableView
you just need to implement the method
- (void)controlTextDidEndEditing:(NSNotification *)obj { ... }
In fact, NSTableView
is the delegate
of the NSControl
elements it contains, and forwards those method calls to its delegate
(There are other methods that are useful)
Otherwise, use the NSNotificationCenter
:
// where you instantiate the table view
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(editingDidEnd:)
name:NSControlTextDidEndEditingNotification object:nil];
// somewhere else in the .m file
- (void)editingDidEnd:(NSNotification *)notification { ... }
// remove the observer in the dealloc
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSControlTextDidEndEditingNotification object:nil];
[super dealloc]
}

- 14,493
- 4
- 32
- 41

- 675
- 1
- 7
- 12
-
1Well, this is either right or wrong, depending on whether you're using cell-based or view-based tables. If you're using cell-based tables and your goal is to write out the changes, this approach won't work because this notification gets sent *before* the tableView:setObjectValue:forTableColumn:row: method gets called to store the values in the data source, so you'll be writing out the old values. – dgatwood Sep 20 '14 at 04:25
-
Actually I'm not getting this notification at all in a view based table view – Jun 16 '15 at 15:58
Set up observers for each item in the content array using addObserver:toObjectsAtIndexes:forKeyPath:options:context:
You will also need to set an observer for the array itself, so that you will be notified about objects that are added to or removed from the array.
For an example look at the iSpend project.

- 23,641
- 2
- 30
- 19
Subclass NSTableView and override textDidEndEditing: (be sure to call super's implementation).
This will only be invoked by text fields NSTextFieldCell or NSComboBoxCell (but only when changing the value by typing it, not by selecting the value from the combo's menu).

- 23,641
- 2
- 30
- 19
Look into the NSTableDataSource protocol. The message you are looking for is called: tableView:setObjectValue:forTableColumn:row:

- 4,674
- 5
- 32
- 43
-
3This is probably the correct answer. With that said, it works only with cell-based table. If you're using a view-based table, that method is never called. – dgatwood Sep 20 '14 at 04:29
Translating @Milly's answer into Swift 3:
// Setup editing completion notifications
NotificationCenter.default.addObserver(self, selector: #selector(editingDidEnd(_:)), name: NSNotification.Name.NSControlTextDidEndEditing, object: nil)
Function to handle notification:
func editingDidEnd(_ obj: Notification) {
guard let newName = (obj.object as? NSTextField)?.stringValue else {
return
}
// post editing logic goes here
}

- 861
- 10
- 22
Subclass NSArrayController and override objectDidEndEditing: (be sure to call super's implementation).
This will mostly only be invoked by text fields NSTextFieldCell or NSComboBoxCell (but only when changing the value by typing it, not by selecting the value from the combo's menu). There may be a few other cells that will invoke it, but I'm not sure which ones. If you have a custom cell then consider implementing the NSEditor and NSEditorRegistration informal protocols.

- 23,641
- 2
- 30
- 19