Thanks Brent for your input:

You will probably want to use KVO to observe changes to the array holding the list of column names to show.

I'm not sure how to do that. It's probably enough in my case to intercept setContent calls to the NSArrayController, changing the table columns during that process.

You can subclass NSArrayController.

I ended up doing that. I only had to intercept setContent and add an IBOutlet instance variable linked to the NSTableView, so I could set up the needed columns based on the newContent:

//  BFArrayController.h

@interface BFArrayController : NSArrayController
{
        IBOutlet NSTableView* myTableView;
}

@property (retain) NSTableView* myTableView;

- (void) setContent: (id) newContent;

@end


//  BFArrayController.m

#import "BFArrayController.h"
#import "BFTableViewCategory.h"

@implementation BFArrayController

@synthesize myTableView;

- (void) setContent: (id) newContent
{
        if ([newContent count] > 0)
        {
                NSArray* columnNameArray = [[newContent objectAtIndex:0] 
allKeys];
                [myTableView createColumns:(NSArray*)columnNameArray 
bindTo:self];
        }
        [super setContent: newContent];
}

@end


And I implemented a new createColumns:bindTo: method as a category for NSTableViews:

//  BFTableViewCategory.h

#import <Cocoa/Cocoa.h>

@interface NSTableView (ExtrasByTom)

- (void) createColumns:(NSArray*)columnNameArray bindTo: (NSArrayController*) tableArrayController;

@end


//  BFTableViewCategory.m

#import "BFTableViewCategory.h"

@implementation NSTableView (ExtrasByTom)

- (void) createColumns:(NSArray*)columnNameArray bindTo: (NSArrayController*) tableArrayController
{
        // Remove old columns:
NSMutableArray* oldTableColumns = [NSArray arrayWithArray: [self tableColumns]];
        for(NSTableColumn* oldTableColumn in oldTableColumns)
                [self removeTableColumn:oldTableColumn];

        // Add new columns:
        for (NSString* columnName in columnNameArray)
        {
NSTableColumn* newTableColumn = [[[NSTableColumn alloc] initWithIdentifier:columnName] autorelease];
                [[newTableColumn headerCell] setStringValue:columnName];
                [self addTableColumn:newTableColumn];
[newTableColumn bind:@"value" toObject:tableArrayController withKeyPath:[NSString stringWithFormat: @"arrangedObjects.%@", columnName] options:nil];
        }
}
@end

You could go all-out and add support for a new binding or the custom controller could just add itself as an observer of the arranged objects property of the relevant array controller (the one managing the list of column names). Then implement the KVO observation method (-observeValueForKeyPath:ofObject:change:context:), where you will do the right thing depending on whether a column was added or removed.


Hmmm, that's interesting. It would be useful to be able to bind the array of NSTableColumns used by an NSTableView to some array in the model data. Probably a bit beyond me at the moment.

Thanks,
Tom
BareFeet

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to