我试图将可绑定属性添加到自定义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 }]
更改选择时,绑定对象不会相应更新。
我做错了什么?
答案 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}}类,你也应该尝试这样做。