Делегат NSTextFieldCell?

У меня есть ячейка текстового поля в представлении таблицы, из которой мне нужно узнать, когда она закончит редактирование. Я думал, что должен установить класс Controller в качестве делегата ячейки текстового поля, а затем использовать метод делегата NSTextField textDidEndEditing:, но понял, что ячейка текстового поля, похоже, не имеет методов делегирования? Почему это, и что я могу сделать (кроме подкласса), чтобы быть проинформированным, когда редактирование закончено?

Спасибо

Ответ 1

NSTextFieldCell наследуется от NSCell (ну, технически из NSActionCell, который наследуется от NSCell). Класс NSCell используется для (из docs):

Класс NSCell предоставляет механизм для отображения текста или изображений в объекте NSView без накладных расходов на полный подкласс NSView.

Примечательно, что класс ячейки используется для "отображения текста или изображений" и не имеет отношения к взаимодействию с пользователем. Аналогично, с классом NSTextField:

Класс NSTextField использует класс NSTextFieldCell для реализации своего пользовательского интерфейса.

NSTextField имеет дело с фактическим вводом пользователя, в то время как с помощью ячейки текстового поля просто реализует свой пользовательский интерфейс, и аналогичным образом методы делегата для предоставления уведомления, когда редактирование текста заканчивается, предоставляется через NSTextField класса, а не через класс NSTextFieldCell.

Если вы хотите получать уведомления о завершении редактирования в NSTableView, вам необходимо зарегистрироваться в качестве наблюдателя NSTextDidEndEditingNotification (вы можете прочитать NSNotificationCenter, если вы не знакомы с уведомлениями). Чтобы сделать это, поместите следующее в свой класс контроллера; функция awakeFromNib - это хорошее место, чтобы включить ее, чтобы убедиться, что она вызвана при запуске вашего приложения:

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
       selector:@selector(textDidEndEditing:)
           name:NSTextDidEndEditingNotification
         object:tableView];

Где tableView - указатель на ваш объект NSTableView. Затем просто реализуйте метод следующим образом:

- (void)textDidEndEditing:(NSNotification *)aNotification
{
    // Do what you want here
}

Не забывайте снимать себя как наблюдателя при освобождении:

- (void)dealloc
{
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    [nc removeObserver:self];
}

Причина, по которой вы устанавливаете объект, который вы наблюдаете как экземпляр NSTableView (а не сама ячейка), заключается в том, что под капотом, когда вы редактируете ячейку в таблице, ячейка, с которой вы работаете не редактируется напрямую; это окно (или пользовательский) редактор полей. Когда редактирование заканчивается, редактор полей затем передает новое значение для этой ячейки в виде таблицы. Однако в представлении таблицы будет отправлено уведомление о том, что ячейка закончила редактирование.

Ответ 2

Внедрить метод tableView:setObjectValue:forTableColumn:row: в протоколе NSTableViewDataSource. Поместите его рядом с методом tableView:objectValueForTableColumn:row:, который вы уже выполнили.

- (void)tableView:(NSTableView *)aTableView
   setObjectValue:(id)anObject
   forTableColumn:(NSTableColumn *)aTableColumn
              row:(NSInteger)rowIndex
{
    [mutableArrayWithStrings replaceObjectAtIndex:rowIndex withObject:anObject];
}