0
votes

I'm having trouble with Columns in NSTableview. I want to add an item to a specific column in an instance of NSTableView. (Note that data is a pointer to an instance of NSMutableArray, which is a property of AppDelegate, which is the dataSource)

-(IBAction)addTask:(id)sender
{
[self.data addObject:@""];
[self tableView:_tableView setObjectValue:@"Hello World" forTableColumn: self.column row:0];
[self.tableView reloadData];
}

A tutorial I went through showed me how to edit a single-column NSTableView. However, using the same implementation of the NSTableViewDataSource methods causes tableView to populate both columns. The pertinent implementation from the tutorial:

-(void)tableView:(NSTableView *)tableView
setObjectValue:(id)object
forTableColumn:(NSTableColumn *)tableColumn
         row:(NSInteger)row
{
[self.data replaceObjectAtIndex:row withObject:object];
}

I reason part of the issue is that the above method doesn't do anything with the tableColumn parameter, but I'm still learning and have no idea how to proceed. (It's especially hard to find help because many modern tutorials involve view-based NSTableViews, and well I know that is best practice, I don't want to run away from this.) I hope my explanation was clear enough, and any help would be much appreciated.

1

1 Answers

0
votes

The reason you are seeing the data populated in multiple columns is you are not differentiating what values go in what columns.

You should think of each item in your array as a row in your table view. If you wish to display different values in columns of that row you need a way to store those different values in the data source object. This can be done by using a concrete model object class that has multiple properties defined or by using a NSDictionary with different keys with their corresponding values.

For adding a row:

-(IBAction)addTask:(id)sender
{
    NSMutableDictionary *newRow = [NSMutableDictionary dictionary];
    [newRow setObject:@"Hello World" forKey:@"salutation"];
    [self.data addObject:newRow];
    [self.tableView reloadData];
}

So for the display code:

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
{
    NSDictionary *row = [self.data objectAtIndex:rowIndex];

    NSString *columnIdentifier = [aTableColumn identifier];

    return [row objectForKey:columnIdentifier];
}

You'll notice we are using the column identifier here. Normally you set this value in Interface Builder on the table column. In the case above the identifier needs to be the same as the key in the dictionary for which you wish to display information.

Finally allowing the user to set a value of a column in the table view:

-(void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger) rowIndex
{
    NSDictionary *row = [self.data objectAtIndex:rowIndex];

    NSString *columnIdentifier = [aTableColumn identifier];

   [row setValue:anObject forKey:columnIdentifier];
}