2015-11-30 2 views
1

Je conserve du code hérité et lorsque je l'ai compilé avec le SDK 10.8 plutôt qu'avec le SDK 10.7, des raccourcis équivalents clés pour certains éléments de menu cessé de travailler. Mon hypothèse est que c'est parce que ces éléments de menu sont dans un état désactivé. Les NSMenuItems qui ne fonctionnent plus sont ceux qui faisaient partie d'un sous-menu où autoenablesItems avait été défini sur NO (j'ai confirmé cela dans le xib via l'inspecteur d'attributs pour ce sous-menu et par programme en interrogeant [NSMenu autoenablesItems]. que l'appel à [NSMenuItem setEnabled:] n'a aucun effet car si je demande [NSMenuItem isEnabled] immédiatement après avoir appelé setEnabled: YES, l'état n'a pas changé et il renvoie toujours NO pour isEnabled. Voici un extrait de code avec la sortie il génère:Le paramètre setEnabled de NSMenuItem ne fonctionne pas même si autoenablesItems est défini sur NO pour NSMenu

printf("DEBUG: Current state of menu item is "); 
[nsMenuItem isEnabled] ? printf("enabled\n") : printf("DISABLED!\n"); 
printf("DEBUG: Current state of menu autoenablesItems is "); 
[nsMenu autoenablesItems] ? printf("YES\n") : printf("NO\n"); 

[nsMenuItem setEnabled:YES]; 

printf("DEBUG: Current state of menu after setting it is "); 
[nsMenuItem isEnabled] ? printf("enabled\n") : printf("DISABLED!\n"); 

sortie:

DEBUG: Current state of menu item is DISABLED! 
DEBUG: Current state of menu autoenablesItems is NO 
DEBUG: Current state of menu after setting it is DISABLED! 

I t également ried sous-classe NSMenuItem et redéfinissant setEnabled pour voir s'il y avait un autre appel à setEnabled qui écrasait mon appel, mais aucun autre appel ne passe par setEnabled.

Si je clique sur le menu parent du sous-menu alors il semble corriger l'état et ces NSMenuItems sont activés, mais il ne passe pas par mon code setEnabled pour changer cet état. J'ai essayé d'ajouter un observateur à la sous-classe activé pour essayer d'attraper où l'état était activé en cliquant sur le menu parent, mais cela ne fournissait aucune information non plus car l'observateur n'était déclenché que pour mes appels à setEnabled ne changent pas réellement l'état. D'après ce que je peux dire en lisant la documentation d'Apple, setEnabled de NSMenuItem devrait fonctionner tant que autoenablesItems est défini sur NO dans le menu parent, mais cela ne semble pas fonctionner dans ce cas, et je ne peux pas comprendre pourquoi.

Dans le même code si j'utilise le SDK 10.7 pour compiler cet appel à setEnabled modifie l'état de NSMenuItem. Quand il entre dans ce code dans la construction 10.7 le NSMenuItem est déjà dans un état activé, mais j'ai essayé de changer l'appel à setEnabled: NO pour confirmer si cela a changé l'état isEnabled, et c'est ce qui a été fait dans la version 10.8 .

Des idées pour lesquelles cela ne fonctionne pas dans 10.8? J'ai aussi essayé avec 10.9 et ça n'a pas marché non plus. J'ai été incapable d'essayer 10.10 ou 10.11 encore puisqu'il y a un autre code qui a besoin d'être mis à jour afin de le compiler avec les plus récents SDK (encore une fois, c'est un vieux code plutôt ancien).

+0

Lorsque ces journaux sont touchés, êtes-vous sûr que nsMenuItem n'est pas en fait nul? Cela entraînerait l'impression de NO pour les deux journaux. Une autre voie d'attaque serait de définir la méthode de validation du menu sur tout objet pertinent (la cible, le premier répondeur) et de voir si (1) il est appelé, et (2) sa valeur de retour est respectée, même lorsque l'auto-habilitation est activée de. Il se passe quelque chose de louche, parce que ce truc est un vieux code et a bien fonctionné dans Cocoa pendant de nombreuses années. Le travail de détective est ce qui est nécessaire. – bhaller

+0

J'ai confirmé que nsMenu et nsMenuItem ne sont pas nuls. J'ai également confirmé qu'après avoir cliqué sur l'élément de menu de niveau supérieur (que nsMenu est un sous-menu de), la prochaine fois que le code est appelé, nsMenu et nsMenuItem sont toujours les mêmes objets (même adresse dans le débogueur) , et que isEnabled retourne alors vrai. La cible sur nsMenuItem est nulle, mais une action est définie. Il a le même état quand cela fonctionne aussi. – user1176103

+0

Lorsque l'équivalent de clé fonctionne, nous nous retrouvons dans le code de l'action définie (via sendEvent de NSApplication suivi de performSelector de NSObject: withObject, suivi de l'action). Lorsque l'équivalent de clé ne fonctionne pas, à partir de sendEvent de NSApplication, nous passons à sendEvent de NSWindow (d'abord via sendEvent de la sous-classe) suivi de _reallySendEvent: isDelayedEvent de NSWindow: suivi de keyDown de la vue. Donc l'action n'est jamais appelée, et je suppose que c'est parce que l'élément de menu est désactivé. – user1176103

Répondre

0

Vous ne savez pas pourquoi la version SDK importerait, mais avez-vous vérifié le menu dans InterfaceBuilder pour vous assurer qu'il n'a pas de liaisons configurées pour l'état "enable"? Ce serait une autre façon pour les objets d'être mystérieusement handicapés.

Dans le cas contraire, un délégué de menu pourrait remplacer les éléments de menu de votre autre code ou désactiver explicitement des éléments. Il y a aussi une méthode NSMenuDelegate

- menuHasKeyEquivalent:forEvent:target:action: 

Ce qui est appelé spécifiquement dans les cas où une clé d'accélérateur a été pressé, et qui peut tout à fait court-circuiter l'état activé/désactivé des éléments de menu.

+0

Pour vérifier les liaisons, regardez-vous l'inspecteur des liaisons? Si c'est le cas, je ne vois pas "Bind to" coché dans l'une des sections. Il n'y a pas non plus d'instance de menuHasKeyEquivalent dans la base de code, donc je ne pense pas que cela puisse être le problème. – user1176103

+0

Bizarre. Je peux vérifier cela avec les SDK 10.10 et 10.11, et un programme de test trivial, les choses fonctionnent comme vous vous attendez - si autoEnablesItems est désactivé pour le menu, setEnabled et isEnabled fonctionnent et retournent le bon résultat. –

+0

Pour répondre à l'autre question - oui, regardez dans l'inspecteur Liaisons, après avoir sélectionné l'élément de menu. –

-1

utilisation simple ceci pour activer/désactiver les éléments du menu

NSMenu *menu = [[NSMenu alloc] init]; 

ajouter l'article de menu désactiver

[menu addItemWithTitle:@"DisableItem" action:nil keyEquivalent:@""]; 

ajouter élément enable menu

[menu addItemWithTitle:@"EnableItem" action:@selector(method:) keyEquivalent:@""];