Attendre [NSAlert beginSheetModalForWindow:...];
Lorsque j'affiche une NSAlert de cette façon, j'obtiens la réponse tout de suite:
int response;
NSAlert *alert = [NSAlert alertWithMessageText:... ...];
response = [alert runModal];
Le problème est que c'est l'application de modal et de ma demande de document de base. Je l'affichage de l'alerte dans le document en cours de la fenêtre par l'aide de feuilles, comme ceci:
int response;
NSAlert *alert = [NSAlert alertWithMessageText:... ...];
[alert beginSheetModalForWindow:aWindow
modalDelegate:self
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
contextInfo:&response];
//elsewhere
- (void) alertDidEnd:(NSAlert *) alert returnCode:(int) returnCode contextInfo:(int *) contextInfo
{
*contextInfo = returnCode;
}
Le seul problème, c'est que beginSheetModalForWindow:
retourne tout de suite j'ai donc fiable ne peut pas demander à l'utilisateur une question et attendre une réponse. Ce ne serait pas une grosse affaire si je pouvais diviser la tâche en deux zones, mais je ne peux pas.
J'ai une boucle qui traite environ 40 différents objets (qui sont dans un arbre). Si un objet ne parvient pas, je veux l'alerte de montrer et de demander à l'utilisateur s'il veut continuer ou abandonner (poursuivre le traitement à la branche courante), mais depuis mon application est le document de base, la Pomme Human Interface Guidelines dicter à l'utilisation des feuilles lorsque l'alerte est spécifique à un document.
Comment puis-je afficher l'alerte fiche et attendre une réponse?
Vous devez vous connecter pour publier un commentaire.
Malheureusement, il n'y a pas beaucoup que vous pouvez faire ici. En gros, vous avez à prendre une décision: la ré-architecture de votre application afin qu'il puisse traiter de l'objet de manière asynchrone ou de l'utilisation non approuvé, obsolète architecture de la présentation de l'application modale des alertes.
Sans connaître toutes les informations au sujet de votre conception réelle et comment vous traite de ces objets, il est difficile de donner toute information complémentaire. Sur le dessus de ma tête, cependant, un couple de réflexion pourrait être:
Cela peut être vraiment compliqué pour ce que vous avez besoin, cependant. Dans ce cas, ma recommandation serait d'aller juste avec le obsolète l'usage, mais cela dépend vraiment de vos besoins de l'utilisateur.
Nous avons créé un catégorie sur
NSAlert
pour lancer des alertes en mode synchrone, tout comme l'application des boîtes de dialogue modales:Le code est disponible via GitHub, et la version actuelle affichée ci-dessous à des fins d'exhaustivité.
Fichier d'en-tête
NSAlert+SynchronousSheet.h
:Mise en œuvre de fichier
NSAlert+SynchronousSheet.m
:La solution est d'appeler
après beginSheetModalForWindow. Aussi, vous devez implémenter un délégué qui attrape la boîte de dialogue "a fermé" de l'action, et des appels [NSApp stopModal] en réponse.
[NSApp stopModalWithCode:returnCode];
de sorte querunModalForWindow
obtient le code est correct.stopModalWithCode:returnCode
dans la réalisation bloc œuvres: L'utilisateur clique sur l'achèvement du bloc s'exécute, puis le code_retour est retourné parrunModalForWindow
.Ici est un NSAlert catégorie qui résout le problème (comme suggéré par Philipp avec la solution proposée par Frédéric et amélioré par Laurent P.: j'utilise un bloc de code au lieu d'un délégué, il est simplifié, encore une fois).
Juste au cas où quelqu'un vient les chercher pour cela (je l'ai fait), j'ai résolu ce problème avec les éléments suivants:
Puis en exécutant un NSAlert de façon synchrone est aussi simple que:
Remarque il est possible de re-entrancy questions discutées, donc faites attention si vous faites cela.
voici ma réponse:
Créer une variable de classe mondiale 'NSInteger alertReturnStatus'
Espère que ça vous aidera,
Cheers
--Hans
C'est la version de Laurent, et coll., ci-dessus, traduit en Swift 1.2 pour Xcode 6.4 (dernière version de travail d'aujourd'hui) et testé dans mon application. Merci à tous ceux qui ont contribué à rendre ce travail! Le standard de la documentation d'Apple m'a donné aucun indice sur comment aller à ce sujet, du moins pas partout que j'ai pu trouver.
Un mystère qu'il me reste: pourquoi j'ai dû utiliser le double point d'exclamation dans la fonction finale. NSApplication.mainWindow est censé être juste une option NSWindow (NSWindow?), droit? Mais le compilateur a donné l'erreur affichée jusqu'à ce que j'ai utilisé le deuxième '!'.
NSApplication.ModalResponse
et vous avez maintenant seulement besoin d'un seul point d'exclamation à la dernière ligne. Nous ne devons le type de fonte à la ligne 6.Contrairement à Windows je ne crois pas qu'il y a un moyen de bloquer sur des boîtes de dialogue modales. L'entrée (par exemple à l'utilisateur de cliquer sur un bouton) seront traitées sur votre thread principal donc il n'y a aucun moyen de blocage.
Pour votre tâche vous devrez passer le message en haut de la pile puis de la reprendre là où vous l'avez laissé.
Quand un objet échoue, arrêtez le traitement des objets dans l'arbre, faire une remarque de quel objet a échoué (en supposant qu'il existe une commande et que vous pouvez reprendre là où vous l'avez laissé), et jeter la feuille. Lorsque l'utilisateur ferme la feuille, ont la
didEndSelector:
méthode de commencer le traitement à nouveau à partir de l'objet qu'il l'a laissée avec, ou n'avez pas, selon lareturnCode
.Vous pouvez utiliser
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
:Espère que ça aide.