zzyzy
zzyzy

Reputation: 983

NSMatrix NSArrayController binding issues --- ugh

I want to manipulate an NSMutableArray property of an array controller which acts at the content for an NSMatrix, without having to manually add the cells to the NSMatrix to which it is bound.

I've spent many hours on this, but to no avail.

Any help would be really appreciated.

I have a programmatically created an NSMatrix in NSListModeMatrix mode. In my NSArrayController subclass, I populate an NSMutableArray with 4 dummy objects to start with, representing 4 rows and 1 column of data. I then bind to that matrix the populated NSMutableArray:

interface:
@property (nonatomic, strong) NSMutableArray *myArray;

implementation (init):
NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary];
[bindingOptions setObject:[NSNumber numberWithBool:YES] forKey:NSInsertsNullPlaceholderBindingOption];
[bindingOptions setObject:[NSNumber numberWithBool:YES] forKey:NSRaisesForNotApplicableKeysBindingOption];

[matrix bind:@"content"
    toObject:self
 withKeyPath:@"myArray"
     options:bindingOptions];

Now I want to add columns to the matrix. For the first addition, this means a set of cells that are indexed at locations 1,3,5,7 with col=1. This is due to the left-to-right, top-to-bottom nature of the NSMatrix backing content array:

NSInteger colCount = [matrix numberOfColumns];
NSInteger rowCount = [matrix numberOfRows];
NSMutableArray *newList = [[NSMutableArray alloc] init];
NSMutableIndexSet *myIndexes = [[NSMutableIndexSet alloc] init];
for (NSInteger i=0; i<rowCount; i++) {
    [newList addObject:[[NSCell alloc] init]];
    [myIndexes addIndex:col+colCount*i];
}

Now, here is what I'd like to do:

  [self.myArray insertObjects:newList atIndexes:myIndexes];

Hoping that the NSMatrix will automatically update. But, alas, no.

I can NSLog to confirm that the array is increasing in size (and is correctly laid out), but nothing updates in the UI unless I do the following instead:

// update the `NSMatrix` manually
  [matrix insertColumn:col withCells:newList];
// update the underlying array
  [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:myIndexes forKey:@"myArray"];
  [self.myArray insertObjects:newList atIndexes:myIndexes];
  [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:myIndexes forKey:@"myArray"];

If I leave out the first line, the NSMatrix is entirely blank.

If I leave out the second & last (willChange/didChange) lines and keep the first line, the matrix only shows the default single column.

In all cases, though, I see the underlying array is growing correctly in size and arrangement.

But I only want to update the underlying mutable array, without having to kludgingly add columns to the NSMatrix myself.

How do I get NSMatrix to play along?

PS: I can shorten the above 4 lines to 2 lines by doing this, ditching the will/did lines:

  [matrix insertColumn:col withCells:newList];
  [[self mutableArrayValueForKey:@"myArray"] insertObjects:newList atIndexes:myIndexes];

Upvotes: 1

Views: 123

Answers (0)

Related Questions