对NSPopUpButton进行子类化以添加可绑定属性

时间:2015-01-26 14:55:57

标签: objective-c cocoa binding nsbutton nspopupbutton

我试图将可绑定属性添加到自定义NSPopUpButton子类。

我已经创建了一个" selectedKey" property,用于存储与所选菜单项关联的NSString。

在控制初始化中,我将self设置为按钮目标和按钮的操作(valueChanged :),然后设置" selectedKey"根据用户选择:

@interface MyPopUpButton : NSPopUpButton {
    NSMutableDictionary *_items;
    NSString *_selectedKey;    
}

@property(nonatomic, readwrite, copy) NSString* selectedKey;
- (void)addItemWithTitle:(NSString *)title andKey:(NSString *)key;

@end

@implementation MyPopUpButton
- (instancetype)initWithFrame:(NSRect)frameRect {

    self = [super initWithFrame:frameRect];
    if (self) {

        _items = [NSMutableDictionary new];
        [NSObject exposeBinding:@"selectedKey"];
        [super setTarget:self];
        [super setAction:@selector(valueChanged:)];

    }
    return self;

}

- (void)addItemWithTitle:(NSString *)title andKey:(NSString *)key {

    [super addItemWithTitle:title];
    [_items setValue:title forKey:key];

}

- (void)valueChanged:(id)sender {

    for (NSString *aKey in [_items allKeys]) {
        if ([[_items valueForKey:aKey] isEqualToString:[self titleOfSelectedItem]]) {
            self.selectedKey = aKey;
        }
    }

}

- (void)setSelectedKey:(NSString *)selectedKey {

    [self willChangeValueForKey:@"selectedKey"];
    _selectedKey = selectedKey;
    [self didChangeValueForKey:@"selectedKey"];

    [self selectItemWithTitle:[_items valueForKey:selectedKey]];

}
@end

这似乎按预期工作:" selectedKey"当用户更改PopUpButton选择时,属性会更改。

不幸的是,尝试绑定此属性并不起作用。

[selectButton bind:@"selectedKey" toObject:savingDictionary withKeyPath:key options:@{NSContinuouslyUpdatesValueBindingOption : @YES }]

更改选择时,绑定对象不会相应更新。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

我创建了一个" selectedKey" property,用于存储与所选菜单项关联的NSString。

绑定绝对是这里的方法,但你使用bind:toObject:withKeyPath:options是不正确的。

传递给第一个参数的值必须是Apple为该特定控件提供的预定义值之一。对于NSPopUpButton个对象,可用值记录在NSPopUpButton Bindings Reference中。查看此文档时,您会发现没有selectedKey选项。但是selectedValue[self.btn bind:@"selectedValue" toObject:self withKeyPath:@"mySelectedString" options:nil]; ,其描述如下:

一个NSString,用于指定NSPopUpButton中所选项目的标题。

因此,设置绑定的正确方法如下:

setSelectedKey

这就是你需要做的全部:当激活动作选择器时,存储在你传入的 keyPath 的属性作为第三个参数已经被更新。这意味着你可以(i)完全摆脱exposeBinding方法,(ii)删除valueChanged:行,以及(iii)删除- (void)awakeFromNib { self.btn.target = self; self.btn.action = @selector(popUpActivity:); [self.btn bind:@"selectedValue" toObject:self withKeyPath:@"mySelectedString" options:nil]; // I've added a couple of additional bindings here; they're // not required, but I thought they'd be instructive. [self.btn bind:@"content" toObject:self withKeyPath:@"myItems" options:nil]; [self.btn bind:@"selectedIndex" toObject:self withKeyPath:@"mySelectedIndex" options:nil]; // Now that you've set the bindings up, use them! self.myItems = @[@"Snow", @"Falling", @"On", @"Cedars"]; self.mySelectedIndex = @3; // "Cedars" will be selected on startup // no need to set value of mySelectedString, because it will be // updated automatically by the selectedIndex binding. NSLog("%@", self.mySelectedString) // -> "Cedars" } - (void)popUpActivity:(id)sender { NSLog(@"value of <selectedIndex> -> %@", self.mySelectedIndex); NSLog(@"value of <selectedString> -> %@", self.mySelectedString); } 中的代码 - Cocoa已经完成了这个位。

以下示例仅实现了两种方法,但是,如果我了解您的意图,那么它们就应该是您所需要的:

NSPopUpButton

值得做的最后一点是,上述任何一个都不应该成为ViewController子类的一部分。看起来你可以 - 因此应该 - 做你需要做的一切而不用这个控件的自定义子类。在我的演示应用程序中,上面的代码属于{{1}}类,你也应该尝试这样做。