Принудительное чтение текстового поля перед исчезновением модального диалога в какао - PullRequest
2 голосов
/ 06 апреля 2009

В приложении Mac OS X Cocoa у меня есть модальное диалоговое окно приложения с текстовыми полями, которые привязаны к Shared User Defaults Controller. Если я отредактирую текстовое поле, а затем уберу из него вкладку, прежде чем нажать кнопку ОК, все будет работать так, как нужно. Однако, если я начинаю редактировать поле, а затем нажимаю клавишу Return, чтобы вызвать OK, старое значение поля остается в NSUserDefaults.

Итак, как я могу заставить измененное поле влиять на связанное значение, когда редактирование "не завершено"?

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

FWIW, вот код, который отображает диалоговое окно:

- (void)showDialog {
    [NSApp activateIgnoringOtherApps:YES];
    [NSApp beginSheet:startTimerDialog
       modalForWindow:nil
        modalDelegate:nil
       didEndSelector:nil
          contextInfo:nil];
    [NSApp runModalForWindow:startTimerDialog];
    [NSApp endSheet:startTimerDialog];
    [startTimerDialog orderOut:self];
}

Кнопка OK (фактически называется «Старт») предназначена для этого метода:

- (IBAction)startTimerDialogStartButtonWasClicked:(id)sender {
    [self closeModalDialog:sender];

    // Then, call methods that read values from NSUserDefaults
    // ...    
}

Ответы [ 4 ]

4 голосов
/ 06 апреля 2009

Отправить пользователю по умолчанию контроллер сообщение commitEditing.

2 голосов
/ 06 апреля 2009

Это может быть ответ:

[startTimerDialog makeFirstResponder:nil];

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

Конечно, первый респондент может отказать в отставке, и в этом случае makeFirstResponder вернет NO. Поэтому мне нужно разобраться, как с этим справиться.

1 голос
/ 06 апреля 2009

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

[startTimerDialog endEditingFor:nil];

Это всегда работает, но немного интенсивнее, чем нужно в большинстве случаев. (более официальное описание "интенсивного" см. В документации ниже) .

Вкратце: -endEditingFor: следует использовать только в качестве крайней меры, если вы не можете заставить fieldEditor уйти в отставку первым респондентом. Поэтому, возможно, вы захотите попробовать более тонкий подход, прежде чем прибегнуть к крайним мерам, подобным этому.

Чтобы быть более тонким, в документации NSWindow для -endEditingFor: Apple предлагает нечто похожее на это:

if ( ![startTimerDialog makeFirstResponder:startTimerDialog] )
    /* Making the window firstResponder failed, proceed to
       force the first responder to resign */

    [startTimerDialog endEditingFor:nil];

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

0 голосов
/ 06 апреля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...