Indeed, my initial assertions were correct – namely, that with an underlying array for content, NSMatrix
lays that content out from left-to-right then top-to-bottom. An array of 10 elements in a 5x2 matrix will be laid out with these indices:
0 1 2 3 4
5 6 7 8 9
So I share with you a couple code snippets... for example, doing a call of [self insColAtIndex:self.matrix.numberOfColumns]
on this result in a new matrix with the new items "X" appended to the last column:
0 1 2 3 4 X
5 6 7 8 9 X
Without further ado, with allocating an initial-sized NSMatrix
with at least 1 column of the desired height of n rows, here's two methods in a sub-classed NSArrayController
to make the controlled NSMatrix
and its content array work in tandem:
// insert NSMatrix column at index (zero-based)
-(void)insColAtIndex:(NSInteger)index
{
NSInteger colCount = self.matrix.numberOfColumns;
if (index<0 || index>colCount)
return;
NSInteger rowCount = self.matrix.numberOfRows;
[self.matrix addColumn];
for (NSInteger i=0; i<rowCount; i++)
[self insertObject:[[NSCell alloc] init] atArrangedObjectIndex:index+colCount*i+i];
}
// remove NSMatrix column at index (zero-based)
-(void)delColAtIndex:(NSInteger)index
{
NSInteger colCount = self.matrix.numberOfColumns;
if (index<0 || index>=colCount)
return;
NSInteger rowCount = self.matrix.numberOfRows;
[self.matrix removeColumn:index];
for (NSInteger i=rowCount-1; i>=0; i--)
[self removeObjectAtArrangedObjectIndex:index+colCount*i];
}
I realize that I could have created an NSMutableIndexSet
with array indices and affected the NSMatrix's array in one fell swoop (with insertObjects:atArrangedObjectIndexes:
and removeObjectsAtArrangedObjectIndexes:
), but that seemed more trouble than it was worth.
The code for inserting/deleting contiguous rows from the array is left as a (much easier) exercise for the reader ;-)