Мне нужно знать, когда пользователь закончит редактирование ячейки в NSTableView. Таблица содержит все календари пользователя (полученные из CalCalendarStore), поэтому для сохранения изменений пользователя мне нужно сообщить CalCalendarStore об изменениях. Однако я не могу найти ничего, что вызывается после того, как пользователь закончит редактирование — я бы предположил, что в делегате таблицы должен быть метод, но я видел только тот, который вызывается при начале редактирования, а не при завершении редактирования.
Как я могу получить уведомление, когда пользователь закончит редактирование ячейки в NSTableView?
Ответы (6)
Подкласс NSTableView и переопределить textDidEndEditing: (обязательно вызовите реализацию super).
Это будет вызываться только текстовыми полями NSTextFieldCell или NSComboBoxCell (но только при изменении значения путем его ввода, а не путем выбора значения из меню комбо).
Вы можете добиться того же результата без создания подкласса NSTableView
, используя методы NSNotificationCenter
или методы NSControl
. См. документацию Apple здесь:
http://developer.apple.com/library/mac/#qa/qa1551/_index.html
Это всего пара строк кода, и они отлично сработали для меня.
Если вы можете быть delegate
из NSTableView
, вам просто нужно реализовать метод
- (void)controlTextDidEndEditing:(NSNotification *)obj { ... }
Фактически, NSTableView
является delegate
из NSControl
элементов, которые он содержит, и перенаправляет вызовы этих методов в свои delegate
(есть и другие полезные методы)
В противном случае используйте 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]
}
Настройте наблюдателей для каждого элемента в массиве контента, используя addObserver:toObjectsAtIndexes:forKeyPath:options:context:
Вам также потребуется установить наблюдателя для самого массива, чтобы получать уведомления об объектах, которые добавляются в массив или удаляются из него.
В качестве примера посмотрите на проект iSpend.
Посмотрите на протокол NSTableDataSource. Сообщение, которое вы ищете, называется: tableView:setObjectValue:forTableColumn:row:
Перевод ответа @Milly на Swift 3:
// Setup editing completion notifications
NotificationCenter.default.addObserver(self, selector: #selector(editingDidEnd(_:)), name: NSNotification.Name.NSControlTextDidEndEditing, object: nil)
Функция для обработки уведомлений:
func editingDidEnd(_ obj: Notification) {
guard let newName = (obj.object as? NSTextField)?.stringValue else {
return
}
// post editing logic goes here
}
Подкласс NSArrayController и переопределение objectDidEndEditing: (обязательно вызовите реализацию super).
В основном это будет вызываться только текстовыми полями NSTextFieldCell или NSComboBoxCell (но только при изменении значения путем его ввода, а не путем выбора значения из меню комбо). Может быть несколько других ячеек, которые будут вызывать его, но я не уверен, какие именно. Если у вас есть пользовательская ячейка, рассмотрите возможность реализации неофициальных протоколов NSEditor и NSEditorRegistration.