Life as Clay

Cocoa Programming for Mac OS X Chapter 6: Challenge: Make a Data Source

with 2 comments

It’s been busy around here. I’ve started and stopped this challenge a few times over the course of a week, but finally returned to it yesterday evening. The time away from it actually made it easier. Armed with the knowledge that most of what I needed to know was in the chapter and that the challenge would be easier than the teachings in the chapter, I dove in and tried to keep it simple. I haven’t made it editable yet, but probably will tackle that tonight, since I think it will be simple. The final app looks like this:

I encountered a few issues. The first was how to make the table update its contents. The mutable array updated and the table view, via its delegate, was monitoring the number of rows it needed to display, etc., but the view didn’t update until I added [toDoTableView reloadData]; to the addIt method that is called when clicking the Add button.

The other thing that wasn’t part of the exercise but that irritated me is that I wanted the text field to be empty after clicking the Add button. I spent a lot of time pouring through the NSTextField documentation and viewing the list of available methods (by hitting escape after typing the object name in a method call… [newItemField ESC…. ). There are so many methods available, due to inheritance. I didn’t see the setStringValue: method in the list, though I knew exactly what I was looking for. Anyhow, I found the answer through a quick Google search.

What next? There are two approaches to making the list editable and I probably will try both of them. One is to add an “Edit” button – select a row in the table, click edit, and the value from that row is put back in the text field and changes are made to the row upon clicking Add and/or Save. The Add button could change to read Save when editing. The second approach is to directly edit into the table, which is easier because it doesn’t involve more interface components.

For now, here’s the code and connections.

#import <Cocoa/Cocoa.h>

@interface AppController : NSObject {
	IBOutlet NSTextField *newItemField;
	IBOutlet NSTableView *toDoTableView;
	IBOutlet NSButton *addButton;
	NSMutableArray *toDoList;
- (IBAction)addIt:(id)sender;



#import "AppController.h"
@implementation AppController

- (id)init
	[super init];

	if (self) {
		toDoList = [[NSMutableArray alloc] init];
	return self;

- (IBAction)addIt:(id)sender;
	NSString *newToDo = [newItemField stringValue];

	// Check for non-zero
	if ([newToDo length] == 0) {
		NSLog(@"New to-do was empty.");

	// NSLog(@"%@", newToDo);

	[toDoList addObject:newToDo];
	[toDoTableView reloadData];	        // Forces the table to reload the data view
	[newItemField setStringValue:@""];      // Clears the text box after adding a new item

	// NSLog(@"%i", [toDoList count]);

- (int)numberOfRowsInTableView:(NSTableView *)tv
	return [toDoList count];

- (id)tableView:(NSTableView *)tv
objectValueForTableColumn:(NSTableColumn *)tableColumn
	NSString *item = [toDoList objectAtIndex:row];
	// NSLog(@"%@", item);
	return item;


The connections in Interface Builder:

To Do AppController Object

To Do Text Field

To Do Add Button

To Do Table View

To Do Table View Attributes


Written by Clay

December 15, 2009 at 13:58

Posted in Cocoa, Code, Objective-C

Tagged with , , ,

2 Responses

Subscribe to comments with RSS.

  1. One more note… The NSMutableArray wasn’t updating at first, but I wasn’t receiving an error or warning. The reason for the rewrite of the init method is to initialize and allocate the NSMutableArray object, since you cannot add To Do items to it without allocating it first.


    December 15, 2009 at 14:02

  2. Sorry Clay, I thought to add this since you helped me in getting up and running with the Cocoa code, and you were planning to added some day. It worked good for me. You can try it and let me know. and thank you.

    // This all you have to do for making the table view editable
    – (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {

    [toDoList replaceObjectAtIndex:rowIndex withObject:anObject];


    Reham Hobus

    November 1, 2010 at 13:20

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: