Part I: Building a To Do List Application for the iPhone
I will break this tutorial up into several parts. The first part will be just on how to create a simple table view app on the iPhone. As we progress I will add more features and explain different interactions.
1. Launch Xcode
2. Click on the File Menu and choose New Project.
You should see a window that asks you to select the template for your new project. Select the "Navigation-Based Application" and click on choose.
3. You will now see a window that is asking you what name to save the project.
Type in the name ToDoList. This will create a project directory called ToDoList and all of the relevant files.
Make sure you have your SDK set to the Simulator. You can change this parameter by selecting from the Xcode menu Project -> Set Active SDK -> Simulator.
Ok, now select Build and Go. You should see the following on your iPhone:

All right so that doesn't look all that amazing, but it isn't bad for not having done any coding and it is at least a good checkpoint that you have compiled and deployed a basic iPhone app.
Now lets dig into all the files that were generated.
What are all these files for?
At first all of these files are a bit intimidating. Lets take a few minutes to discuss what these files are:
Info.plist
This is a property list file that is responsible for some of the initial settings for your application. The most important things to note right now is that it has the Main NIB file set to MainWindow. What is a NIB file? A NIB file is really just an XML file that is used to build the interface. Helper applications like Interface Builder will store information about your user interface in that file.
main.m
This is the program that launches the main application loop held in the UIApplicationMain class.
MainWindow.xib
This is the NIB file which holds the settings for the main interface window.
If you were to double click on the MainWindow.xib file from XCode it would launch Interface Builder and you would see the following:
File's Owner: This class represents the class that deals with the User Interface. By default it delegates the responsibility of the class to the class called ToDoListAppDelegate which was automatically created for you when you chose the project template.
First Responder: This handles the first responder actions. Don't worry about it for now.
To Do List App Delegate: This class is delegated all the actions from the File's Owner class. It is also automatically has its outlets connected to the Navigation Controller and the Window in the user interface.
Window: This is the window where your user interface will be displayed.
Navigation Controller: This class manages navigation through a hierarchy of views. It already has the RootViewController View already associated with it.
RootViewController.h
This is the header file for the RootViewController class. You can see from the header that the RootViewController class is of type UITableViewController. This means that the RootViewController will manage a TableView which is defined in the RootViewController.xib NIB file.
RootViewController.m
Within this file you can see where several methods are generated and commented out for you. This provides you a base line to start programming your table view.
Let's review those functions that are active and see what they do:
- (void)didReceiveMemoryWarning
This method is called by the iPhone OS and is telling it that it needs to have more memory. This is a good place to free up any cached data or non-essential data.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
This method is called to determine how many different sections are in the TableView. It passes in the parameter of a specific table view. By default this is set to return 1, but we will show how you can have multiple sections in a table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
This asks the view how many rows of data are there available in this table view to display. By default it returns 0. As we define data in the view we will allow that number to change.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
This method is called to ask what Table View Cell to display for the table view based on the index path. Simple way to think about this is that for each row indicated by the index path, this method generates a TableViewCell which encapsulates everything in that row.
Right now they create a generic table view cell and modify the text for that cell.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
This methods asks the controller what to do when a row is selected. Typically in drill down data you would then push on another view controller to show the detailed data.
- (void)dealloc
For all of you who haven't done a lot of C programming and/or memory management this is the routine that gets called to release itself. Here you want to release any variables that you allocated and are managing within the class. I will talk through this more when we actually start adding some variables to the class.
ToDoList_Prefix.pch
This file holds the pre-compiled headers to include. Basically it loads in the Foundation and UIKit Libraries to be linked into your application
ToDoListDelegate.h
This is the header file for the Delegate class that is automatically created for your project. You will note that this class implements the UIApplicationDelegate protocol which defines methods that are expected to be handled on behalf of the application.
It also defines two variables which it uses. One is for the UIWindow class and the second is for the UINavigationController class which we have shown in the MainWindow NIB file
Something to note is that the class uses the @property macro to define the variables. This enables the creation of the header descriptors for the getter and setter methods defined in the class.
For example:
@property (nonatomic, retain) IBOutlet UIWindow *window
The parameters non-atomic and retain specify how the memory management works for those methods. You can learn more about it here.
You may have noticed the IBOutlet term in there and wondered what kind of definition is that? IBOutlet is simply a null-defined macro:
#define IBOutlet
Which is used by Interface Builder to determine which properties of a class are available as an Outlet.
ToDoListDelegate.m
Within this class there are several methods defined for you:
- (void)applicationDidFinishLaunching:(UIApplication *)application
This method is called after the application has launched this is the opportunity to configure your main window to be viewed.
As you can see this method connects the view in UINavigationController which is the RootViewController view, and then it tells the Window to show itself.
- (void)applicationWillTerminate:(UIApplication *)application
This is a placeholder method to add in any code that you want added in before the application terminates.
- (void)dealloc
Inside this method both the navigationController and window memory references are released.
Ok, So let's make a basic to do list
For now we want to do the following:
1. Display the title 'To Do List'
2. Have a list of to do tasks listed on the view
Feature 1: Add the title to the To Do List
1. Double click on the MainWindow.xib file. This will launch interface builder. View it in list mode and expand the Navigation Controller till you expose the Navigation Item for the Root View Controller. It should look like this:

2. Now open the Attributes Inspector by clicking on the menu Tools -> Attribute Inspector.
3. Set the title to 'To Do List'
4. Save the file
5. Return to Xcode
6. Build and run the application again you should see the following:

Feature 2: Have a list of to do tasks listed on the view
We need to track a list of to do tasks.
1. Open up the ToDoListAppDelegate.h file:
We want to create a property that stores the list of to do tasks. We will call the property list and give it a type of NSMutableArray.
We also need to provide means for the views to determine how many To Do tasks they are to be displayed. We create a function called countOfToDoList to return that.
We also need to return the text of the To Do List task based upon the index of the task in the list. We create a function called toDoTaskInListAtIndex passing in the index to the list to retrieve it.
Add the following lines in bold so that your code looks like this:
@interface ToDoListAppDelegate : NSObject{
UIWindow *window;
UINavigationController *navigationController;
NSMutableArray *list;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
- (NSUInteger) countOfToDoList;
- (NSString *) toDoTaskInListAtIndex:(NSUInteger)theIndex;
@property (nonatomic, retain) NSMutableArray *list;
@end
2. Open up the ToDoListAppDelegate.m file:
We need to synthesize the getter and setter methods for the list property.
We need to define the methods we declared in the header.
We need to be sure to release the list that we create to keep track of the to do list items.
Update your code with the updates in bold so it looks like this:
@implementation ToDoListAppDelegate
@synthesize window;
@synthesize navigationController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
self.list = [NSMutableArray arrayWithObjects:@"Task #1", @"Task #2", @"Task #3",nil];
// Configure and show the window
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Save data if appropriate
}
- (void)dealloc {
[list release];
[navigationController release];
[window release];
[super dealloc];
}
#pragma mark ToDoListAppDelegate Actions
- (NSUInteger) countOfToDoList{
return [list count];
}
- (NSString *) toDoTaskInListAtIndex:(NSUInteger)theIndex{
return [list objectAtIndex:theIndex];
}
@synthesize list;
@end
3. Open up the RootViewController.m file:
Right now only the delegate knows about the to do list tasks. We need to let the RootViewController know how to get the count of items.
The RootViewController asks for the count in the - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section method.
What we want to do is call the ToDoListAppDelegate and ask it for the count and pass it to the method. We will update that method with the following code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
ToDoListAppDelegate *appDelegate = (ToDoListAppDelegate *)[[UIApplication sharedApplication] delegate];
return [appDelegate countOfToDoList];
}
Now that we have the count we need to render the correct task name when the row is called in the view. We do so with the following changes in bold:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
ToDoListAppDelegate *appDelegate = (ToDoListAppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *taskName = [appDelegate toDoTaskInListAtIndex:indexPath.row];
cell.text = taskName;
return cell;
}
4. Now if we save everything and rebuild and deploy it should look like:

Summary
This was a fast introduction to building a very basic To Do List App for the iPhone. In Part II I will show you how to dynamically add new data, as well as remove existing data.
If you had any problems creating this on your own, I have attached a copy of my build ToDoList.tar.gz
Labels: iPhone, Simple, TableView, To Do List, Tutorial



0 Comments:
Post a Comment
<< Home