4 votes

Comment masquer un élément de menu avec une vue personnalisée ?

J'utilise une vue personnalisée très simple (contenant uniquement un champ NSTextField en lecture seule et un contrôle NSSegmentedControl) dans un NSMenuItem (en utilisant l'interface de l'utilisateur). -setView: ). Cette partie fonctionne comme prévu.

Voici le problème : dans le -menuNeedsUpdate: Méthode de délégation NSMenu Je cache conditionnellement l'élément de menu. Lorsque j'appelle [item setHidden:YES] Dans le cas d'une vue personnalisée, l'élément de menu avec une vue personnalisée ne se cache pas, mais les autres éléments de menu "classiques" le font.

Ma vue personnalisée est construite dans son propre XIB, et j'y accède par un NSViewController personnalisé.

Mise à jour

L'élément de menu reste visible même si je coche la case Caché dans Interface Builder, et que je supprime la ligne où il est caché dans le code.

Mise à jour 2

J'ai aussi essayé de mettre hidden sur la vue personnalisée avant et après le réglage hidden sur l'élément de menu. Le résultat est comme si l'élément de menu n'était pas caché, mais que la vue l'était ; les contrôles de la vue ne sont pas visibles, mais il y a toujours un vide là où ils devraient être.

Mise à jour 3

J'ai modifié la méthode d'Apple MenuItemView exemple de code pour masquer un des éléments du menu après son ajout (insertion [menuItem setHidden:YES]; à la ligne 87), et cela a le même effet que dans mon code (c'est-à-dire aucun).

Je commence à penser que la seule façon de cacher cet élément de menu sera de définir sa vue sur nil quand j'ai besoin de le cacher et de le remettre quand j'ai besoin de le montrer, mais il ne semble pas que cela doive être nécessaire.

Mise à jour 4

En utilisant la réponse de Mike ci-dessous, voici le code que j'utilise :

// Declared in the header file
IBOutlet NSMenuItem *previousMenuItem;
IBOutlet NSMenuItem *togglingMenuItem; //Needs to be RETAINED

. . .

- (void)menuNeedsUpdate:(NSMenu *)menu {
    BOOL hideItem = YES; // Some criteria, obviously

    // Remove the menu item, if it was already present
    if ([menu indexOfItem:togglingMenuItem] >= 0) {
        [menu removeItem:togglingMenuItem];
    }

    // Put it back if it should be visible
    if (!onePageVisible) {
        [menu insertItem:togglingMenuItem
                 atIndex:[menu indexOfItem:previousMenuItem] + 1];
    }
}

1voto

Rayfleck Points 9842

Plutôt que de cacher un élément, pouvez-vous l'enlever/le rajouter selon les besoins ?

 [rootMenu removeItemAtIndex: 23];

1voto

askh Points 31

Dans la méthode de délégation du menu menu:updateItem:atIndex:shouldCancel : je trouve mon élément de menu de vue personnalisée par balise et je fixe sa vue à nil s'il est caché ou je lui attribue une vue personnalisée s'il est visible :

- (BOOL)menu:(NSMenu *)menu 
    updateItem:(NSMenuItem *)item 
    atIndex:(NSInteger)index 
    shouldCancel:(BOOL)shouldCancel
{

    if ([item tag] == CUSTOM_VIEW_TAG)
    {
        [item setView:[item isHidden]?nil:customView];
        return NO; //we've done our dirty work
    }

    return YES;
}

1voto

Honghao Zhang Points 430

En Swift, vous pouvez remplacer isHidden et mettre view en conséquence :

class PositionHeaderMenuItem: NSMenuItem {
    let customView = SomeCustomView()

    override var isHidden: Bool {
        didSet {
            if isHidden {
                view = nil
            } else {
                view = customView
            }
        }
    }
}

0voto

Francis McGrew Points 5227

J'ai dû remplacer la méthode setHidden : de NSMenuItem et définir la hauteur de la vue à zéro si elle est cachée, comme suit :

- (void) setHidden:(BOOL)flag {

[super setHidden:flag];

NSView *view = [self view];
[view setHidden:flag];

// if our view is hidden, give it a zero height so it won't draw at all
if (flag)
    [view setFrameSize:NSMakeSize([view frame].size.width, 0)];
else {

    [view setFrameSize:NSMakeSize([view frame].size.width, [self menuItemHeight])];
}

}

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