Il m'a fallu un peu d'expérimentation pour dissiper une certaine confusion sur l'Objectif-C "ModalForWindow" de la langue et, par la suite, comment utiliser un modal de la session. Peut-être les conseils suivants peuvent vous sauver quelqu'un certain temps:
(Dans le cas où vous êtes nouveau dans le concept: Quand une fenêtre, généralement un panneau, s'exécute modal, il empêche une autre partie de l'application à partir de répondre jusqu'à ce qu'elle a été rejetée.)
"ModalForWindow" signifie des choses différentes dans des circonstances différentes. Si vous utilisez loadNibNamed pour afficher un panneau définie par un xib et vous voulez qu'il fonctionne modal, appelez cela une fois qu'il est affiché:
// Make panelReviewImports modal, so that no other part of app will respond.
[[NSApplication sharedApplication] runModalForWindow:self.panelReviewImports];
et un suivi auprès de son licenciement méthodes:
[[NSApplication sharedApplication] stopModal];
Mais pour NSAlert, la "fenêtre" dans beginSheetModalForWindow se réfère à la fenêtre à laquelle l'alerte sera attaché comme une feuille, la fenêtre sera gelé jusqu'à ce que l'alerte est rejeté. Mais l' application ne sera pas gelé; toutes les autres fenêtres restera accessible. Si vous souhaitez joindre une alerte comme une feuille et aussi congeler le reste de l'application, suivez les beginSheet code avec un simple appel à runModal et utiliser le code de retour explicitement, comme ceci:
[alert beginSheetModalForWindow:self.window
modalDelegate:self didEndSelector:@selector(abandonmentAlertDidEnd:returnCode:contextInfo:)
contextInfo:nil];
NSInteger returnCode = [alert runModal];
[self abandonmentAlertDidEnd:alert returnCode:returnCode contextInfo:nil];
(Bien sûr, vous avez mis en œuvre le abandonmentAlertDidEnd:code_retour:contextInfo: code d'une méthode de classe.)
Ou, si vous voulez l'exécution de l'alerte comme un centré sur panneau, appel runModal par lui-même.
Supposons que vous souhaitez exécuter un panneau modal, suivie par une alerte si l'utilisateur soumet une entrée non valide. Vous auriez à stopModal avant de vous montrer le qui - vive- après qui, pour une raison quelconque, un autre appel à runModalForWindow ne fonctionne pas correctement. Pour ce scénario, vous avez besoin d'un modal de la session:
1) Ajouter une NSModalSession propriété de votre contrôleur de classe, parce que le modalSession doit être accessible à travers de multiples méthodes.
2) une Fois que vous avez affiché le panneau d'appel beginModalSessionForWindow pour instancier le modalSession:
self.modalSession = [[NSApplication sharedApplication] beginModalSessionForWindow:self.panelForInput];
3) Suivez ce avec un tout-boucle qui appelle runModalSession, la rupture lors de son retour n'est pas égale à NSRunContinuesResponse:
while ([[NSApplication sharedApplication] runModalSession:self.modalSession] == NSRunContinuesResponse)
continue;
La boucle se rompre et l'application va libérer lorsque l'utilisateur clique sur l'un des panneau de boutons. (En tapant dans le panneau textfield laissera le modal session intacts).
4) Dans votre gestion du bouton, si l'entrée utilisateur n'est pas valide, vous appelez une alerte avec runModal.
5) Immédiatement au-dessous de l'alerte d'appel, dans le code qui sera exécuté une fois l'alerte est rejetée, vous mettez le même lors de la boucle ci-dessus. Le panneau modal de session reprend.
6) Dans votre traitement pour fermer le panneau, soit au moment de l'entrée valide ou d'annuler, vous appelez endModalSession, qui, curieusement, n'est pas suffisante, vous devez également appeler stopModal, même si vous n'avez jamais appelé runModalForWindow.
[[NSApplication sharedApplication] endModalSession:self.modalSession];
[[NSApplication sharedApplication] stopModal];
[self.panelForInput close];