2013-12-05 3 views
4

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

  • NSWindow загружается из СИБА с NSWindowController, который является также его делегировать
  • Пара NSTextField-х с NSNumberFormatter
  • Использование привязок, в NSTextField 's связываются с целыми свойствами в NSWindowController (я не использовал NSObjectController для простоты, но может добавить его в случае необходимости)
  • A «сделал» NSButton которого пользователь щелкает, когда закончите, чтобы принять изменения и закрыть окно
  • В windowShouldClose: методы контроллера сделать окончательные проверки и решить, могу ли я закрыть окно

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

  • NSTextField должен принимать только номер для него конечного значения, которое также больше нуля
  • Если пользователь пытается вставить не числовые значения или ноль, должно быть предупреждением, приглашающим пользователь зафиксировать его записи
  • Когда пользователь нажимает на сделано:
    • ли другие пользовательские проверки (например, сравните, если один номер отлично, чем другой)
    • Если значения верны, примите изменения и закройте окно («модель» должна быть обновлена ​​со значениями через привязки)
    • Если значения неверны, пользователь должен быть предложено с выбором того, чтобы исправить запись (оставив окно открытым) или закрыть окно и отменить изменения

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

Проблема № 1:

Я не мог найти способ, чтобы изменить сообщение об ошибке, отображаемое пользователю в боевой готовности, когда NSTextField теряет фокус и значение неправильно что-то более описательное. Есть какой-либо способ сделать это? Или мне нужно каким-то образом реализовать собственный NSFormatter?

Проблема № 2:

Когда пользователь изменяет значение в NSTextField и нажимает на кнопку «Готово», Cocoa не рассматривает это как триггер для обновления значения модели NSTextField является оценка к. Это может быть стандартное поведение OSX, но это не имеет никакого смысла.

Мне удалось обойти это, позвонив по телефону [window makeFirstResponder:nil] в действие кнопки «done», чтобы заставить NSTextField потерять фокус и обновить значение, но мне интересно, правильно ли это для этого.

Проблема № 3:

А вот где я действительно чесать голову. Если пользователь вводит неверное значение (например, не целое число) в NSTextField и нажимает кнопку «done», проверка не срабатывает, а NSTextField будет продолжать иметь неправильные значения, пока модель не обновляется.

Я ожидаю, что предупреждение «недействительное» будет отображаться, и у меня есть место для ввода кода, чтобы принять решение о закрытии окна или нет, но я не смог найти способ переопределить это поведение.

Какова должна быть стандартная практика для достижения этих требований? Должен ли я отказаться от форматирования и/или привязок и просто делать все это вручную, используя действия?

+1

Попробуйте «Постоянно обновлять значение» и «Проверяет немедленно» в инспекторе Bindings в разделе «Значение». Что касается кнопки. Я просто попробовал '[[self window] endEditingFor: nil]'; (Найдено с google), который работал до окончания редактирования. Но и код после запуска. Он не ждет ответа. Таким образом, вам нужно будет добавить что-то, чтобы остановить это, если лист предупреждений опущен ... Я думаю, что в прошлом я просто вручную получил значения и сделал свою собственную проверку и оповещения. – markhunte

+0

«Непрерывно обновляет значение» не то, что я хочу. Он принудительно обновляет каждое изменение в NSTextField и принудительно обновляет, когда пользователь вводит часть значения, только преждевременно отказываясь от проверки, не имея намерений пользователя. «Проверяет немедленно», похоже, не работает как рекламируемый, он влияет на то, является ли проверка : метод error: вызывается или нет на объекте модели и не влияет на форматтер. – danielv

+0

В моей базовой установке; текстовые поля привязаны к дефолтам по умолчанию для общих пользователей. «Это значение» использует «Постоянное обновление значения», которое не устанавливает валидацию и предупреждение. Проверка выполняется только тогда, когда редактирование завершено. (Думая об этом, это хорошо, значит, Validates немедленно не работает.) – markhunte

ответ

1

Для проблемы 1 попробуйте установить делегат для текстовых полей и реализовать -control:didFailToFormatString:errorDescription: и, возможно, -control:didFailToValidatePartialString:errorDescription:. Представьте любой пользовательский интерфейс, который вы хотите, используя описание ошибки или нет.

В качестве альтернативы вы можете реализовать собственный подкласс NSNumberFormatter и переопределить -getObjectValue:forString:errorDescription: и -isPartialStringValid:proposedSelectedRange:originalString:originalSelectedRange:errorDescription:. Вы можете позвонить в супер для большей части реализации. Если это не удается, вы можете заменить описание ошибки, которое super поставляется с другим. Вы бы использовали этот подход, если вам нужен контекст объекта форматирования (его свойства и т. Д.), Чтобы выяснить лучшее описание ошибки.

Правильное решение проблемы 2 состоит в том, чтобы не программно изменить первого ответчика. Скорее, вы действительно должны использовать NSObjectController для посредничества между текстовыми полями и оконным контроллером. В методе действий для кнопки «Готово» позвоните либо -commitEditing, либо -commitEditingWithDelegate:didCommitSelector:contextInfo:. NSObjectController наследует эти методы от NSController, который принимает протокол NSEditor. Когда вы получаете результат (синхронно для первого, асинхронно для последнего), вы либо выполняете, либо ничего не делаете в зависимости от того, выполнено или не выполнено коммит.

Я подозреваю, что проблема 3 также является результатом программного изменения первого ответчика окна. Часто бывает, что программные изменения не подвергаются тем же проверкам, что и соответствующее изменение, сделанное в результате действия пользователя. Фреймворки предполагают, что программист знает, что вы делаете, и поэтому было бы «неправильно» подвергнуть программную смену фокуса проверке с помощью форматирования, например.

Смежные вопросы