views:

222

answers:

3

I am working along with Cocoa Programming For Mac OS X (a great book). One of the exercises the book gives is to build a simple to-do program. The UI has a table view, a text field to type in a new item and an "Add" button to add the new item to the table.

On the back end I have a controller that is the data source and delegate for my NSTableView. The controller also implements an IBAction method called by the "Add" button. It contains a NSMutableArray to hold the to do list items. When the button is clicked, the action method fires correctly and the new string gets added to the mutable array. However, my data source methods are not being called correctly. Here they be:

- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView {
    NSLog(@"Calling numberOfRowsInTableView: %d", [todoList count]);
    return [todoList count];
}

- (id)tableView:(NSTableView *)aTableView
objectValueForTableColumn:(NSTableColumn *)aTableColumn
row:(NSInteger)rowIndex {
    NSLog(@"Returning %@ to be displayed", [todoList objectAtIndex:rowIndex]);
    return [todoList objectAtIndex:rowIndex];
}

Here is the rub. -numberOfRowsInTableView only gets called when the app first starts, not every time I add something new to the array. -objectValueForTableColumn never gets called at all. I assume this is because Cocoa is smart enough to not call this method when there is nothing to draw. Is there some method I need to call to let the table view know that its data source has changed, and it should redraw itself?

+4  A: 
-[NSTableView reloadData];

(as a couple of good minutes with the NSTableView API reference would have told you.)

Barry Wark
I did put some effort into looking, just in the wrong place. I checked the Table View Programming Guide, NSTableViewDataSource API reference and NSTableViewDelegate API reference. It seems obvious when you know where it is already.
Jergason
Fair enough. Good luck.
Barry Wark
Don't get me started on trying to find the method for a particular task when it might be spread out over (deity of your choice) only knows how many classes and protocols. It's the major weaknesses in the documentation. To actually use an unfamiliar class, you have to read the docs for the class, all the classes it inherits from and all the protocols it inherits or uses. Wacky fun.
TechZen
@TechZen Fair enough. There seems to be a disconnect between the topic guides and the API docs where the topic guides don't always lead you to the right API docs.
Barry Wark
A: 

I got stuck at the same point on the book. Tried the reloadData to no avail ([toDoTableView reloadData];). It gets and displays the first value I put into the array in AppController.m init, but never reloads after I add anything else to array. Is the instance only accessible from the nib or something?!?! I know its adding to array because I display the count in the logs. Am i missing something really simple?

some relevent snippits of the code:

AppController.h:

~~~

NSMutableArray *items;

IBOutlet NSTableView *toDoTableView

~~~

AppController.m

~~~

-(IBAction)createNewItem:(id)sender{//add an item to array
    NSLog(@"create new item");
    NSString *itemFieldText = [newItemField stringValue];

    //if not empty - add item name to array
    if ([itemFieldText length] >0){
        [items addObject:(id)itemFieldText];
        [itemFieldText release];
        NSLog(@"items in array: %d",[items count]);
        //clear textbox
        NSLog(@"clear text field");
        [newItemField setStringValue:@"" ];
        [toDoTableView reloadData];//refresh the table view?
    }else{
        NSLog(@"Empty, ignoring");
    }

}

~~~

PLEASE HELP !!!

A: 

ok so it was a connection in IB that went missing! also the array went a bit funny with the [itemFieldText release]; so i removed that line too!