Отображение модального окна NSAlert «Да-Нет» и получение значения в рамках того же метода

Итак, скажем, у меня есть такой метод, который используется для проверки того, был ли изменен document, перед его фактическим закрытием:

- (BOOL) canCloseDocument:(id)document
{
     if ([document modified])
     CONFIRM_ALERT(@"Close Document", 
                      @"Are you sure you want to close this document?", 
                      [[core browser] window], 
                      @selector(confirm:code:context:),
                      nil);
     else
          return YES;
}

В этом случае будет вызван метод confirm:code:context:, и canCloseDocument НИЧЕГО не вернет.

Вот мое определение CONFIRM_ALERT :

#define CONFIRM_ALERT(X,Y,Z,W,V) \
NSAlert* confirmAlert = [NSAlert alertWithMessageText:X \
defaultButton:@"OK" \
alternateButton:@"Cancel" \
otherButton:nil \
informativeTextWithFormat:Y]; \
[confirmAlert beginSheetModalForWindow:Z \
modalDelegate:self \
didEndSelector:W \
contextInfo:V];

Вопрос:

Как я могу сделать так, чтобы лист предупреждений отображался, а значение (нажато OK? Нажато отмена?) извлекалось в том же методе (canCloseDocument:), чтобы он мог возвращать либо YES, либо NO?


person Dr.Kameleon    schedule 06.04.2012    source источник


Ответы (1)


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

Если вы хотите получить ответ до того, как вернетесь, вы должны использовать модальное оповещение. Создайте оповещение, а затем вызовите для него -runModal вместо -beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:.

Однако это не позволяет пользователю делать что-либо еще с вашим приложением, пока он не закроет модальное предупреждение. Обратите внимание, что это не просто присуще модальному предупреждению, это присуще вашему желанию, чтобы -canCloseDocument: не возвращался, пока не будет получен ответ. Это означает, что поток выполнения не возвращается в основной цикл событий, что позволяет взаимодействовать с вашим приложением.

person Ken Thomases    schedule 06.04.2012
comment
Я использовал runModal:, но он не отображается в виде листа... так как мне это сделать? Как это делает NSOpenPanel? (это то же самое, не так ли?) - person Dr.Kameleon; 06.04.2012
comment
Я пытался выразить то, что вы можете либо быть модальным, или вы можете использовать лист, но вы не можете делать и то, и другое. Листы по своей сути не модальны. (Мы говорим о том, что они оконно-модальные, но это не модальные в том смысле, в котором вы хотите, когда они могут обрабатываться синхронно в ходе одного вызова метода.) NSOpenPanel также не делает того, что вам нужно. - person Ken Thomases; 07.04.2012