An issue with a multi-column NSTableView

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

  1. Stardock macrumors newbie

    Joined:
    Jan 9, 2009
    #1
    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 cocoadev.com. 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:

    AppController.m:
    Code:
    - (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)
    		return;
    	[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])
    		return;
    	[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

    Joined:
    Jan 10, 2009
    Location:
    India
    #2
    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

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

    Code:
    - (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

    Joined:
    Jan 11, 2009
    #4
    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.

    Code:
    // 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