Cocoa 基于视图的NSTableView中的NSPoupButton:使绑定正常工作 问题描述
我正在尝试实现一些简单且相当常见的功能:在bindings-populated NSTableView中有一个bindings-PopupButton。Apple在其文档中对基于单元格的表进行了描述,如下所示: 对于基于视图的表,我无法使其工作。无论我做什么,“作者”弹出窗口都不会自行填充 我有两个数组控制器,一个用于表中的项(项),另一个用于作者(作者),两者都与核心数据模型中的相应实体关联。我在interface builder中将NSManagedPopup绑定到我的单元格中,如下所示:Cocoa 基于视图的NSTableView中的NSPoupButton:使绑定正常工作 问题描述,cocoa,nstableview,cocoa-bindings,nspopupbutton,Cocoa,Nstableview,Cocoa Bindings,Nspopupbutton,我正在尝试实现一些简单且相当常见的功能:在bindings-populated NSTableView中有一个bindings-PopupButton。Apple在其文档中对基于单元格的表进行了描述,如下所示: 对于基于视图的表,我无法使其工作。无论我做什么,“作者”弹出窗口都不会自行填充 我有两个数组控制器,一个用于表中的项(项),另一个用于作者(作者),两者都与核心数据模型中的相应实体关联。我在interface builder中将NSManagedPopup绑定到我的单元格中,如下所示:
- 内容->作者(控制器键:arrangedObjects)
- 内容值->作者(控制器键:arrangedObjects,模型键路径:name)
- 所选对象->表格单元格视图(模型键路径:objectValue.author
我已经尝试过的事情
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
NSView *view = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
if ([tableColumn.identifier isEqualToString:@"Author") {
AuthorSelectorCell *authorSelectorCell = (AuthorSelectorCell *)view;
[authorSelectorCell.popupButton bind:NSContentBinding toObject:self.authors withKeyPath:@"arrangedObjects" options:nil];
[authorSelectorCell.popupButton bind:NSContentValuesBinding toObject:self.authors withKeyPath:@"arrangedObjects.name" options:nil];
[authorSelectorCell.popupButton bind:NSSelectedObjectBinding toObject:view withKeyPath:@"objectValue.author" options:nil];
}
return view;
}
弹出窗口显示可能的作者列表,但当前选择始终显示为“无值”。如果我添加
[authorSelectorCell.popupButton bind:NSSelectedValueBinding toObject:view withKeyPath:@"objectValue.author.name" options:nil];
当前所选内容完全为空。显示当前所选内容的唯一方法是设置
[authorSelectorCell.popupButton bind:NSSelectedObjectBinding toObject:view withKeyPath:@"objectValue.author.name" options:nil];
它将在我选择其他作者时立即中断,因为它将尝试将NSString*
分配给author*
属性有什么想法吗?也有同样的问题并发现了-基本上是用一个IBOutlet将您的作者数组控制器从nib中取出,并通过文件所有者绑定到它。我也有同样的问题。我已经在Github上展示了这是可能的 有人向作者建议了一种使用IBOutlet属性的变通方法 阵列控制器,但这似乎对我也不起作用
这是对我有效的方法,如中所示。谜题中缺少的一点是,阵列控制器的IBOUTLE必须位于提供TableView委托的类中。您可以尝试NSPopUpbutton的这四个+1设置: 在我的例子中,“所有人”等同于您的“作者”。 我在文件所有者中有所有可用的人员作为财产(NSArray*) 此外,我将tableView委托绑定到文件的所有者。如果没有绑定,我只会得到一个默认列表:Item1、Item2、Item3
我总是喜欢编程方法。在NSTableCellView上创建一个类别:
+(instancetype)tableCellPopUpButton:(NSPopUpButton **)popUpButton
identifier:(NSString *)identifier
arrayController:(id)arrayController
relationship:(NSString *)relationshipName
relationshipArrayController:(NSArrayController *)relationshipArrayController
relationshipAttribute:(NSString *)relationshipAttribute
relationshipAttributeIsScalar:(BOOL)relationshipAttributeIsScalar
valueTransformers:(NSDictionary *)valueTransformers
{
NSTableCellView *newInstance = [[self alloc] init];
newInstance.identifier = identifier;
NSPopUpButton *aPopUpButton = [[NSPopUpButton alloc] init];
aPopUpButton.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
[aPopUpButton bind:NSContentBinding //the collection of objects in the pop-up
toObject:relationshipArrayController
withKeyPath:@"arrangedObjects"
options:nil];
NSMutableDictionary *contentBindingOptions = [NSMutableDictionary dictionaryWithDictionary:[[TBBindingOptions class] contentBindingOptionsWithRelationshipName:relationshipName]];
NSValueTransformer *aTransformer = [valueTransformers objectForKey:NSValueTransformerNameBindingOption];
if (aTransformer) {
[contentBindingOptions setObject:aTransformer forKey:NSValueTransformerNameBindingOption];
}
[aPopUpButton bind:NSContentValuesBinding // the labels of the objects in the pop-up
toObject:relationshipArrayController
withKeyPath:[NSString stringWithFormat:@"arrangedObjects.%@", relationshipAttribute]
options:[self contentBindingOptionsWithRelationshipName:relationshipName]];
NSMutableDictionary *valueBindingOptions = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSAllowsEditingMultipleValuesSelectionBindingOption,
[NSNumber numberWithBool:YES], NSConditionallySetsEditableBindingOption,
[NSNumber numberWithBool:YES], NSCreatesSortDescriptorBindingOption,
[NSNumber numberWithBool:YES], NSRaisesForNotApplicableKeysBindingOption,
[NSNumber numberWithBool:YES], NSValidatesImmediatelyBindingOption,
nil];;
@try {
// The object that the pop-up should use as the selected item
if (relationshipAttributeIsScalar) {
[aPopUpButton bind:NSSelectedValueBinding
toObject:newInstance
withKeyPath:[NSString stringWithFormat:@"objectValue.%@", relationshipName]
options:valueBindingOptions];
} else {
[aPopUpButton bind:NSSelectedObjectBinding
toObject:newInstance
withKeyPath:[NSString stringWithFormat:@"objectValue.%@", relationshipName]
options:valueBindingOptions];
}
}
@catch (NSException *exception) {
//NSLog(@"%@ %@ %@", [self class], NSStringFromSelector(_cmd), exception);
}
@finally {
[newInstance addSubview:aPopUpButton];
if (popUpButton != NULL) *popUpButton = aPopUpButton;
}
return newInstance;
}
+ (NSDictionary *)contentBindingOptionsWithRelationshipName:(NSString *)relationshipNameOrEmptyString
{
NSString *nullPlaceholder;
if([relationshipNameOrEmptyString isEqualToString:@""])
nullPlaceholder = NSLocalizedString(@"(No value)", nil);
else {
NSString *formattedPlaceholder = [NSString stringWithFormat:@"(No %@)", relationshipNameOrEmptyString];
nullPlaceholder = NSLocalizedString(formattedPlaceholder,
nil);
}
return [NSDictionary dictionaryWithObjectsAndKeys:
nullPlaceholder, NSNullPlaceholderBindingOption,
[NSNumber numberWithBool:YES], NSInsertsNullPlaceholderBindingOption,
[NSNumber numberWithBool:YES], NSRaisesForNotApplicableKeysBindingOption,
nil];
}
你找到解决方案了吗?我也有同样的问题。哦,老兄,这让我非常疯狂,谢谢你的解决方案。绑定到我文件所有者的数组控制器IBOutlet(而不是同一nib中的数组控制器对象!)工作正常。给我留下深刻印象的是,有人提交过雷达吗?感谢你引导我找到解决方案。另一个关键信息是将弹出窗口的选定对象绑定到表格单元格视图(Model key Path=objectValue.propertyName);这在最初的问题中提到过,但大多数教程似乎没有充分强调这一点。(苹果的文章确实提到了这一点,但没有提到弹出菜单。)