I\'m trying to achieve something that should be simple and fairly common: having a bindings populated NSPopupButton inside bindings populated NSTab
I always prefer the programmatic approach. Create a category on 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];
}
Had the same problem and found this workaround - basically get your authors array controller out of nib with a IBOutlet and bind to it via file owner.
I had the same problem. I've put a sample project showing this is possible on Github.
Someone suggested a workaround using an IBOutlet property to the Authors array controller but this doesn't seem to work for me either.
This is the approach that did work for me, and that is demonstrated in the sample project. The missing bit of the puzzle is that that IBOutlet to the array controller needs to be in the class that provides the TableView's delegate.
You can try this FOUR + 1 settings for NSPopUpbutton:
In my example, "allPersons" is equivalent to your "Authors". I have allPersons available as a property (NSArray*) in File's owner.
Additionally, I bound the tableView delegate to File's owner. If this is not bound, I just get a default list :Item1, Item2, Item3