textShouldEndEditing не вызывается в NSTableView

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

Мне нужно проверить, является ли имя нового объекта уникальным в хранилище данных, поэтому я не могу использовать для этого средство форматирования. Я думаю, что идеальный момент, когда я должен это проверить, это всякий раз, когда пользователь пытается зафиксировать значение имени записи, используя textShouldEndEditing:,

Я подкласс NSTableView и переопределить следующие методы, просто чтобы иметь возможность проверить в журнале, если они вызваны.

- (BOOL)textShouldEndEditing:(NSText *)textObject {
    NSLog(@"textSHOULDendEditing fired in MyTableView");
    return [super textShouldEndEditing:textObject];
}
- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor {
    NSLog(@"control:textShouldEndEditing fired in MyTableView");
    return YES;
}
- (void)textDidEndEditing:(NSNotification *)aNotification {
    NSLog(@"textDIDEndEditing fired in MyTableView");
}

textDidEndEditing: называется нормально, но textShouldEndEditing: не.

В Ссылке класса NSTableView, под Методами делегата текста, оба метода textShouldEndEditing: а также textDidEndEditing: перечислены. Кто-то, пожалуйста, объясните, почему одному звонят, а другому нет.


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

Я пытался объявить NSTextFieldCell как выход в моем NSTableView, Я также попытался объявить несколько протоколов в NSTableView,

#import <AppKit/AppKit.h>
#import <Cocoa/Cocoa.h>
@interface MyTableView : NSTableView <NSTextDelegate, NSTextFieldDelegate, NSControlTextEditingDelegate, NSTableViewDelegate, NSTableViewDataSource> {
}
@end

Не смейтесь, я даже пытался объявить мой табличный вид своим собственным делегатом:P

3 ответа

Решение

Я переопределил -(void)awakeFromInsert; в (подклассе) управляемого объекта, чтобы создать уникальное значение по умолчанию для свойства name.

Кроме того, я не переопределил -(BOOL)textShouldEndEditing: метод в табличном представлении. Вместо этого я проверяю, является ли вновь введенное свойство name уникальным в (подклассе) управляемого объекта. -(BOOL)validate<Key>:error:,

Вместе две вышеупомянутые стратегии приводят к уникальным свойствам имени во всех управляемых объектах.

Может быть, я мог бы заставить NSTextFieldCell перейти в режим редактирования, в результате чего -(BOOL)textShouldEndEditing: звонить каждый раз.


Некоторые замечания, хотя:

Похоже на то -(BOOL)textShouldEndEditing: возвращает НЕТ, когда -(BOOL)validate<Key>:error: возвращает НЕТ.

И то и другое -(BOOL)textShouldEndEditing: а также -(BOOL)validate<Key>:error: методы вызываются только тогда, когда пользователь действительно вносит изменения в свойство.

После того, как я целый день ломал голову над этой проблемой, не находя окончательного ответа в документации Apple, я решил поделиться найденным решением на тот случай, если кто-то еще столкнется с той же проблемой.

Согласно документации, как упоминалось в оригинальном постере, методы control:textShouldBeginEditing а также control:textShouldEndEditing из NSControlTextEditingDelegate должен быть вызван непосредственно на делегата:

Это сообщение отправляется элементом управления непосредственно его делегированному объекту.

Кроме того, Apple выпустила Технический раздел вопросов и ответов под названием " Обнаружение начала и конца сеансов редактирования ячейки в NSTableView", где четко указано следующее:

A: Как определить начало и конец сеансов редактирования ячейки в NSTableView?

Чтобы определить, когда пользователь собирается начать и завершить сеанс редактирования ячейки вNSTableView Вы должны быть установлены в качестве делегата этой таблицы и реализовать следующееNSControlметоды делегата:

- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor;

- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor;

Таблица перенаправляет сообщение делегата, которое оно получает из текстового представления, на ваш объект делегата, используяcontrol:textShouldEndEditing:метод. Таким образом, ваш делегат может быть проинформирован о том, какой элемент управления редактора поля текстового представления действует от его имени.

Яничего не нашел в документации Apple, где говорится что-то другое, и если кто-то это сделает, указатель на документацию будет очень признателен.

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

Решение

Однако некоторые эвристические тесты, которые я выполнил, показали, что эти методы делегата вызываются для делегата таблицы на основе представления, если (и насколько я знаю: и только если):

  • Делегат таблицы установлен.
  • Делегат редактируемого элемента управления установлен.

Если вы удалите любой из делегатов, методыNSControlTextEditingDelegateПротокол не будет вызван.

В соответствии с (единственной) документацией неожиданным является назначение делегата редактируемого элемента управления. С другой стороны, установка объекта делегата для получения уведомлений делегата звучит довольно интуитивно для меня, и именно поэтому я попытался в первую очередь. Но есть подвох! Любопытно, что этого недостаточно. Если делегат таблицы удален, NSControlTextEditingDelegate методы не будут вызываться, даже если установлен делегат редактируемого элемента управления (что для меня самое странное).

Надеюсь, что это поможет кому-то еще не терять время на этот вопрос.

В своем вопросе вы упоминаете вставку "управляемого объекта", и это было проблемой. Кажется, вы используете таблицу на основе представления, но метод textShouldEndEditing: вызывается только для таблиц на основе ячеек.

Другие вопросы по тегам