An issue with a multi-column NSTableView

Discussion in 'Mac Programming' started by Stardock, Jan 9, 2009.

  1. Stardock macrumors newbie

    Jan 9, 2009
    Hello. I'm trying to learn Cocoa, and I thought for my first application I'd try to make a simple recipe manager. I ran into some issues and along the way and in trying to figure it out I ran into some of the excellent tutorials here at That said, I'm still having issues. Basically I'm wanting to implement a multi-column table view that the user clicks a button to add a new row and then can edit. Currently I've got it where the table view loads a blank row that I can double click and change, but it will not save any changes made. Here's the code of the controller:

    - (void)awakeFromNib
    	//create our original array
    	items = [NSMutableArray new];
    - (id)selectedRowItemforColumnIdentifier:(NSString *)anIdentifier {
    	if ([ingredientTable selectedRow] != -1)
    		return [[items objectAtIndex:[ingredientTable selectedRow]] objectForKey:anIdentifier];
    	return nil;
    - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row {
    	if (row != -1)
    		return [[items objectAtIndex:row] objectForKey:[tableColumn identifier]];
    	return nil;
    - (void)setItems:(NSMutableArray *)anArray {
    	if (items == anArray)
    	[items release];
    	items = anArray;
    	[items retain];
    	[ingredientTable reloadData];
    - (void)addRow:(NSDictionary *)item {
    	[items insertObject:item atIndex:[items count]];
    	[ingredientTable reloadData];
    - (void)removeRow:(unsigned)row {
    	[items removeObjectAtIndex:row];
    	[ingredientTable reloadData];
    - (int)numberOfRowsInTableView:(NSTableView *)tableView {
    	return [items count];
    //occurs when the add row button is clicked
    - (IBAction)add:(id)sender
    	NSMutableDictionary *dict;	
    	dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
    			@"", @"Quantity", 
    			@"", @"Ingredient", nil]; 
    	[self addRow:dict];
    //occurs when the remove row button is clicked
    - (IBAction)remove:(id)sender
    	if ([ingredientTable selectedRow] < 0 || [ingredientTable selectedRow] >= [items count])
    	[items removeObjectAtIndex:[ingredientTable selectedRow]];
    	[ingredientTable reloadData];	

    I'm sure I'm missing something simple, but I would appreciate any guidance and help you could give.
  2. atulkash macrumors newbie

    Jan 10, 2009
    Hi i am also facing the same issue. can u plz tell me if u got the solution.

    Hi i am also facing the same issue. can u plz tell me if u got the solution.i tried but could not manage to add abalnk row it self.

  3. Stardock thread starter macrumors newbie

    Jan 9, 2009
    Ok, so after many headaches I think I need to call this function:

    - (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject
       forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
    	[ingredientTable reloadData];
    I'm not really sure how I'm supposed to tie the data to the column though, my columns are named "Quantity" and "Ingredient" and intuitively I think I'd use that information. Anyone know?
  4. xjayx macrumors newbie

    Jan 11, 2009
    I got this to work for button cells. I haven't tried it yet for text fields, but something like this should work.

    When the user makes changes, the NSCell for the changed field fires an action message. You must receive this action message, update the correct NSDictionary with the changes, then tell the table to reaload.

    // setup the call-back
    NSTableColumn *column = [table tableColumnWithIdentifier:@"some column id"];
    NSTextFieldCell *cell = [column dataCell];
    [cell setAction:@selector(updateTextField:)];
    [cell setTarget:self];
    // recieve update message		
    - (IBAction) updateTextField: (id) sender {
    	NSMutableDictionary *row;
    	NSInteger rowNum;
    	NSTableColumn *column;
    	NSTextFieldCell * cell;
    	NSString * cellValue;
    	column = [table tableColumnWithIdentifier:@"some column id"];
    	cell = [column dataCell];
    	cellValue = [cell stringValue];
    	rowNum = [table selectedRow];
    	row = [rows objectAtIndex: rowNum];
    	[row setValue:cellValue  forKey:@"some column id"];
    	[table reloadData];

Share This Page