textShouldEndEditing не вызывается в NSTableView - PullRequest
1 голос
/ 03 апреля 2012

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

Мне нужно проверить, является ли имя нового объекта уникальным в хранилище данных, поэтому я не могу использовать для этого средство форматирования. Я думаю, что идеальный момент, когда я должен это проверить, это всякий раз, когда пользователь пытается зафиксировать значение имени записи, используя 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 Class Reference , фактически реализует методы манипулирования текстом для объекта NSTextField.

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

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

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

Ответы [ 3 ]

6 голосов
/ 16 июня 2014

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

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

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

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

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

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

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

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

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

Я обнаружил ничего в документации Apple, где указано что-то другое, и если кто-то делает,указатель документации действительно был бы оценен.

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

A Решение

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

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

Если удалить какой-либо делегат, методы протокола NSControlTextEditingDelegate не будут вызываться.

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

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

1 голос
/ 18 июля 2012

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

0 голосов
/ 16 апреля 2012

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

Кроме того, я не переопределил метод -(BOOL)textShouldEndEditing: в табличном представлении,Вместо этого я проверяю, является ли вновь введенное свойство имени уникальным в (10000 *.

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

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


Хотя некоторые замечания:

Кажется,-(BOOL)textShouldEndEditing: возвращает NO, когда -(BOOL)validate<Key>:error: возвращает NO.

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

...