Как я могу получить уведомление, когда пользователь закончит редактирование ячейки в NSTableView?

Мне нужно знать, когда пользователь закончит редактирование ячейки в NSTableView. Таблица содержит все календари пользователя (полученные из CalCalendarStore), поэтому для сохранения изменений пользователя мне нужно сообщить CalCalendarStore об изменениях. Однако я не могу найти ничего, что вызывается после того, как пользователь закончит редактирование — я бы предположил, что в делегате таблицы должен быть метод, но я видел только тот, который вызывается при начале редактирования, а не при завершении редактирования.


person Andy    schedule 11.10.2008    source источник


Ответы (6)


Подкласс NSTableView и переопределить textDidEndEditing: (обязательно вызовите реализацию super).

Это будет вызываться только текстовыми полями NSTextFieldCell или NSComboBoxCell (но только при изменении значения путем его ввода, а не путем выбора значения из меню комбо).

person Nathan Kinsinger    schedule 12.10.2008

Вы можете добиться того же результата без создания подкласса 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]
}
person Milly    schedule 26.08.2012
comment
Ну, это либо правильно, либо неправильно, в зависимости от того, используете ли вы таблицы на основе ячеек или на основе представлений. Если вы используете таблицы на основе ячеек и ваша цель — записать изменения, этот подход не будет работать, поскольку это уведомление отправляется до вызова метода tableView:setObjectValue:forTableColumn:row: для хранения значений в источнике данных, поэтому вы будете записывать старые значения. - person dgatwood; 20.09.2014
comment
На самом деле я вообще не получаю это уведомление в табличном представлении на основе представления. - person Erik Aigner; 16.06.2015

Настройте наблюдателей для каждого элемента в массиве контента, используя addObserver:toObjectsAtIndexes:forKeyPath:options:context:

Вам также потребуется установить наблюдателя для самого массива, чтобы получать уведомления об объектах, которые добавляются в массив или удаляются из него.

В качестве примера посмотрите на проект iSpend.

person Nathan Kinsinger    schedule 12.10.2008

Посмотрите на протокол NSTableDataSource. Сообщение, которое вы ищете, называется: tableView:setObjectValue:forTableColumn:row:

person Lounges    schedule 11.10.2008
comment
Это, вероятно, правильный ответ. При этом он работает только с таблицей на основе ячеек. Если вы используете таблицу на основе представления, этот метод никогда не вызывается. - person dgatwood; 20.09.2014

Перевод ответа @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
}
person J.beenie    schedule 07.09.2017

Подкласс NSArrayController и переопределение objectDidEndEditing: (обязательно вызовите реализацию super).

В основном это будет вызываться только текстовыми полями NSTextFieldCell или NSComboBoxCell (но только при изменении значения путем его ввода, а не путем выбора значения из меню комбо). Может быть несколько других ячеек, которые будут вызывать его, но я не уверен, какие именно. Если у вас есть пользовательская ячейка, рассмотрите возможность реализации неофициальных протоколов NSEditor и NSEditorRegistration.

person Nathan Kinsinger    schedule 12.10.2008