Подтвердить что ты не робот

Советы по NSApps ModalForWindow, NSAlerts ModalForWindow и ModalSession

Мне потребовалось немного экспериментов, чтобы устранить некоторую путаницу в языке Objective-C s "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];

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

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

Предположим, вы хотите запустить групповой модальный, за которым следует предупреждение, если пользователь отправляет недопустимую запись. Вы должны остановитьModal, прежде чем показывать предупреждение, после чего по какой-то причине другой вызов 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];
4b9b3361

Ответ 1

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