NSMenuItem的标题不是通过绑定更新

时间:2012-02-03 16:37:02

标签: objective-c cocoa

在通过绑定更新菜单项的标题时遇到一些麻烦。除了通过绑定之外,我没有在任何地方设置标题,并且当项目首次添加到菜单时标题设置正确。但是,如果绑定选择器中的值发生变化,它就不会改变。

我也将相同菜单项的enabled属性绑定到同一个选择器,并且它正在自我更新。

如果我遵循执行,看起来@“title”绑定只会在设置绑定时触发一次。但是,每次子菜单显示时,@“启用”绑定都会触发。

这是我正在尝试做的事情:

- (void)addToMenu:(MyObject *)myObject
{
    NSInteger insertIndex = [[myStatusItem menu] indexOfItemWithTitle:@"My Placeholder"] + 1;

    NSMenuItem *newMenuItem = [[NSMenuItem alloc] initWithTitle:[myObject name] action:nil keyEquivalent:@""];
    [newMenuItem setIndentation:1];

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

    NSMenuItem *newSubMenuItem = [[NSMenuItem alloc] init];

    // This works great! Different return values from myBoolMethod affect the enabled attribute every time the menu is shown
    [newSubMenuItem bind:@"enabled" toObject:myObject withKeyPath:@"myBoolMethod" options:
        [NSDictionary dictionaryWithObjectsAndKeys:myInverseBoolTransformer, NSValueTransformerBindingOption, nil]];

    // This sets the correct menu item title when FIRST drawn. However, every subsequent time the menu is shown, the title is still set to its init value
    [newSubMenuItem bind:@"title" toObject:myObject withKeyPath:@"myBoolMethod" options:
        [NSDictionary dictionaryWithObjectsAndKeys:myTitleFromBoolTransformer, NSValueTransformerBindingOption, nil]];

    [newSubMenuItem setTarget:myObject];
    [newSubMenuItem setAction:@selector(doStuffThatChangesIndirectlyChangesBoolMethod)];

    [newSubMenu insertItem:newSubMenuItem atIndex:0];
    [newMenuItem setSubmenu:newSubMenu];

    [[myStatusItem menu] insertItem:newMenuItem atIndex:insertIndex];
}

@implementation myTitleFromBoolTransformer

+ (Class)transformedValueClass { return [NSString class]; }
+ (BOOL)allowsReverseTransformation { return YES; }
- (id)transformedValue:(id)value {

    BOOL boolValue = [value boolValue];

    if(boolValue){
        return @"This is the DISabled value";
    } else {
        return @"This is the ENabled value";
    }
}

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您可以一起跳过绑定并使用menu validation(在验证方法中设置标题)。

绑定更加昂贵。

答案 1 :(得分:0)

添加答案是因为我找到了可行的方法,但我不会立即接受,因为我仍然希望听到其他人的意见。

我直接绑定到一个方法,因为我想运行一些代码来检查一个我无法获得通知的值。我认为通过这样做,每次KVO触发读取时它都会执行该选择器(即方法)。好吧,我想我并不真正理解KVO,因为这不是标题所发生的事情。

我最终观察了我的菜单NSMenuDidBeginTrackingNotification以触发检查我的值的代码,然后在myObjectwill/didChangeValueForKey中设置BOOL值。

对于为什么@"enabled"绑定在没有will/didChangeValueForKey消息的情况下工作,我仍然感到很困惑。编辑:请参阅this apple discussion了解启用的原因。我真的需要重新阅读KVC / KVO文档:(