NSPopupButton in view based NSTableView: getting bindings to work

前端 未结 4 892
北海茫月
北海茫月 2021-02-06 10:44

Problem Description

I\'m trying to achieve something that should be simple and fairly common: having a bindings populated NSPopupButton inside bindings populated NSTab

4条回答
  •  Happy的楠姐
    2021-02-06 10:50

    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];
    }
    

提交回复
热议问题