29 votes

Conseils sur ModalForWindow de NSApp, ModalForWindow de NSAlert et ModalSession

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];

3voto

Wienke Points 2682

La question est la réponse. Je poste juste ceci pour le fermer. Désolé d'avoir tordu le format stackoverflow.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X