Вопрос есть ответ. Я просто отправляю это, чтобы закрыть это. Извините за скручивание формата stackoverflow.

отребовалось немало экспериментов, чтобы прояснить некоторую путаницу с языком Objective-C «ModalForWindow» и, впоследствии, как использовать модальный сеанс. Возможно, следующие советы помогут кому-то сэкономить время:

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

«ModalForWindow» означает разные вещи в разных обстоятельствах. Если вы используете loadNibNamed для отображения панели, определенной XIB, и хотите, чтобы она запускалась модально, вызовите ее, как только она отобразится:

// Make panelReviewImports modal, so that no other part of app will respond.
[[NSApplication sharedApplication] runModalForWindow:self.panelReviewImports];

и проследите за этим в его методах увольнения:

[[NSApplication sharedApplication] stopModal];

Но для NSAlert «окно» в beginSheetModalForWindow ссылается на окно, к которому будет отправлено предупреждениеприложенный в виде листа, какое окно будет заморожено до тех пор, пока предупреждение не будет отменено. Ноприложение не замерзнет; все остальные окна останутся работоспособными. Если вы хотите прикрепить предупреждение в виде листа итакже заморозьте оставшуюся часть приложения, выполните код beginSheet с помощью простого вызова runModal и явно используйте код возврата, например, так:

[alert beginSheetModalForWindow:self.window 
                  modalDelegate:self didEndSelector:@selector(abandonmentAlertDidEnd:returnCode:contextInfo:) 
                    contextInfo:nil];
NSInteger returnCode = [alert runModal];
[self abandonmentAlertDidEnd:alert returnCode:returnCode contextInfo:nil];

(Разумеется, вы реализовали в качестве метода класса AbononmentAlertDidEnd: returnCode: contextInfo: code.)

Или, если вы хотите, чтобы оповещение работало как центрированная панель, вызовите runModal отдельно.

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

1) Добавьте свойство NSModalSession в ваш класс контроллера, потому что modalSession должен быть доступен для нескольких методов.

2) Как только вы отобразите панель, вызовите beginModalSessionForWindow, чтобы создать экземпляр modalSession:

self.modalSession = [[NSApplication sharedApplication] beginModalSessionForWindow:self.panelForInput];

3) Затем следует цикл while, который вызывает runModalSession, прерываясь, когда его возвращение не равно NSRunContinuesResponse:

while ([[NSApplication sharedApplication] runModalSession:self.modalSession] == NSRunContinuesResponse)
    continue;

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

4) При обработке кнопок, если запись пользователя недействительна, вы вызываете предупреждение с помощью runModal.

5) Сразу под вызовом оповещения, в коде, который будет выполняться после прекращения оповещения, вы вставляете тот же цикл while, что и выше. Модальная сессия панели возобновляется.

6) При закрытии панели при действительном вводе или отмене вы вызываете endModalSession, что, как ни странно, недостаточно; Вы также должны вызвать stopModal, даже если вы никогда не вызывали runModalForWindow.

[[NSApplication sharedApplication] endModalSession:self.modalSession];
[[NSApplication sharedApplication] stopModal];
[self.panelForInput close];

Ответы на вопрос(1)

Ваш ответ на вопрос