Как скрыть пункт меню с пользовательским представлением? - PullRequest
4 голосов
/ 03 мая 2011

Я использую очень простое пользовательское представление (содержащее только NSTextField и NSSegmentedControl только для чтения) в NSMenuItem (используя метод -setView:). Эта часть работает как положено.

Вот проблема: в методе делегата -menuNeedsUpdate: NSMenu я условно скрываю пункт меню. Когда я звоню [item setHidden:YES], пункт меню с пользовательским представлением не скрывается, а другие «ванильные» пункты меню скрываются.

Мое собственное представление построено на собственной XIB, и я обращаюсь к нему через пользовательский NSViewController.

Обновление

Пункт меню остается видимым, даже если я установил флажок Скрытый в Интерфейсном Разработчике и удалил строку, где он скрыт в коде.

Обновление 2

Я также пытался установить hidden в пользовательском представлении до и после установки hidden в пункте меню. В результате, как будто пункт меню не скрыт, а вид; элементы управления представления не видны, но в них все еще есть место, где они должны быть.

Обновление 3

Я изменил образец кода Apple MenuItemView , чтобы скрыть один из пунктов меню после его добавления (вставьте [menuItem setHidden:YES]; в строке 87), и он имеет тот же эффект, что и в моем коде (то есть , нет).

Я начинаю думать, что единственный способ скрыть этот пункт меню - установить его представление на nil, когда мне нужно его скрыть, и вернуть его обратно, когда мне нужно показать его, но это не похоже это должно быть необходимо.

Обновление 4

Используя ответ Майка ниже, вот код, который я использую:

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

Ответы [ 3 ]

1 голос
/ 03 мая 2011

Вместо того, чтобы скрыть элемент, вы можете удалить / повторно добавить по необходимости?

 [rootMenu removeItemAtIndex: 23];
0 голосов
/ 09 марта 2012

В методе делегата меню menu: updateItem: atIndex: shouldCancel: я нахожу свой элемент меню пользовательского представления по тегу и устанавливаю его вид равным nil, если он скрыт, или назначаю пользовательский вид, если он видим:

- (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;
}
0 голосов
/ 03 мая 2011

Мне пришлось переопределить метод setHidden: NSMenuItem и установить высоту представления равной нулю, если она скрыта, например:

- (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])];
}

}

...