Добавить режимы редактирования для привязки NSFormCell - PullRequest
0 голосов
/ 05 декабря 2011

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

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

Я реализовал это тремя различными способами:

  1. Метод пользовательского установщика в классе модели
  2. Делегат редактирования текста, реализующий NSControlTextEditingDelegate
  3. Вспомогательный класс, который использует KVO, чтобы заметить изменение и инициировать последующее изменение

Все три реализации имеют проблемы.Проблемы, соответственно:

  1. Это поведение не относится к модели.Я должен иметь возможность установить атрибут в коде, например, без его запуска.
  2. Я не могу получить значение «до», потому что ячейка формы не обеспечивает controlTextDidBeginEditing: вызовов (и старыйзначение уходит к моменту вызова controlTextDidEndEditing:).Кроме того, вкладки в поле и из него без ввода чего-либо вызывают вызов controlTextDidEndEditing:.
  3. Когда для изменения пользователя запускается наблюдение, и я инициирую последующее изменение этого свойства, представление игнорирует уведомление об изменениии не перерисовывает.(Я предполагаю, что механизм связывания делает это для эффективности. Обычно при обновлении модели он может игнорировать наблюдения КВО с обновляемого поля.)

Как бы вы решили эту проблему?

1 Ответ

0 голосов
/ 06 декабря 2011

После некоторого обсуждения здесь , звучит как несколько возможных способов сделать это:

  1. Поместите категорию в класс модели и переопределите validateMyKey
  2. Подклассы NSFormCell

Я пробовал оба. Больше вопросов:

  1. validateMyKey не вызывается до тех пор, пока не обновится сама модель, поэтому старое значение недоступно.
  2. editWithFrame:inView:editor:delegate:event: не всегда вызывается при вводе поля, поэтому трудно получить доступ к старому значению в endEditing:.

Новое решение - уточнение моего оригинального # 2: делегат редактирования текста, реализующий NSControlTextEditingDelegate.

Вместо controlTextDidBeginEditing: и controlTextDidEndEditing: реализовать только control:textShouldEndEditing:. В этом методе при необходимости измените текст, затем верните YES.

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

-(BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor {
    NSCell *cell = [(NSForm *)control selectedCell];
    NSString *identifier = [(NSCell *)[(NSForm *)control selectedCell] identifier];
    if (!identifier) return YES;

    NSDictionary *bindingInfo = [cell infoForBinding:@"value"];
    if (!bindingInfo) return YES;
    NSString *oldValue = [[bindingInfo valueForKey:NSObservedObjectKey] valueForKeyPath:[bindingInfo valueForKey:NSObservedKeyPathKey]];

    NSString *newValue = cell.stringValue;

    if ([identifier isEqualTo:@"firstField"]) {
        if (criteria)
            cell.stringValue = ....;

    } else if ([identifier isEqualTo:@"secondField"]) {
        if (criteria)
            cell.stringValue = ....;
    }

    return YES;
}
...