Add Arrows to rows

I found a something a bit late what would of been nice to cover before. I guess it is better late then never right?

In offical IPhone apps there are arrows on each row you can click on that mean you can click here to users. We want to add these nice little arrows.

So open up RootViewController.m and look for the function cellForRowAtIndexPath and in the if (cell == nil) {} block you want to add a link for accessoryType so it looks like

	if (cell == nil) {
		cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
		cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
	}

Your lists should now look like

No source code for this since it was just a one line change

Create a new class

So now that we have a working navigation based application. (download source here) We now want to move the data outside to a seperate class. We do this so we can use the data around the application and not just RootViewController class.

Do you get why? Its so we can use the data in the next view we will get into later.

So the first thing you want to do is create a data holder class. I will call it DataController.m/.h. So the first thing you want to do is right click on the Classes folder on the left hand menu. Then go Add -> New File.

You want to choose the NSObject subclass.

Give it the name DataController. Now that the file is created you will see you have two new files in Classes called DataController.h and DataController.m.

Now we want to move the array over. So the DataController.h looks like

#import 

@interface DataController : NSObject {
    NSMutableArray *menuArray;
}

@property (nonatomic, copy, readwrite) NSMutableArray *menuArray;

- (NSInteger)getCount;
- (id) getItem:(NSInteger)index;
- (void)createData;

@end

So you can see we moved the menuArray array in and we also added a new function called getCount. Later we will use that to return the number of items in the menuArray

So open up the DataController.m. So below @implementation DataController we want to synthesize the array so now your .m file looks like

@implementation DataController

@synthesize menuArray;

@end

You use the @synthesize keyword to tell the compiler that it should synthesize the setter and/or getter methods for the property if you do not supply them within the @implementation block.

So now we need to init the data in the class.

So we need to add an init function. Below the @synthesize you want to add something that looks like

- (id)init {
    if (self = [super init]) {
        [self createData];
    }
    return self;
}

So now we need to create a createDemo function in the class. What I am basically doing is moving all the array items from the RootViewController over to this function.

-(void) createData {
	menuArray = [[NSMutableArray alloc] init];

	[menuArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:
						  NSLocalizedString(@"Hello World", @""), @"title",
						  nil,
						  nil]];

	[menuArray addObject:[NSDictionary dictionaryWithObjectsAndKeys:
						  NSLocalizedString(@"Hello Universe", @""), @"title",
						  nil,
						  nil]];
}

Now we want to return the count of the current array to an outside class. So we add in this function.

-(NSInteger)getCount {
	return [menuArray count];
}

We also need to return the item. Since we are displaying these items it will help to return an item at a given index. So add this function in also

- (id)getItem:(NSInteger)index {
    return [menuArray objectAtIndex:index];
}

So what that function says is when called it expects a index to come in as a NSInteger type. It will use that to get the item at that index in the menuArray and it will return it.

Now you want to remove all the instances of menuArray in the RootViewController.h and RootViewController.m. Since we are not using it anymore.

So now back to the RootViewController.m. We need to initialize our new DataController class, so in the viewDidLoad function we want to add the following.

    DataController *controller = [[DataController alloc] init];
    self.dataController = controller;
    [controller release];

Now in the numberOfRowsInSection, we want to return the current count of the menuArray that is now inside the DataController. This is why we made the getCount function, so we can get that count.

So the function should now look like this

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	return [dataController getCount];
}

Now look for the cellForRowAtIndexPath function and you need to add in setting up the text

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

	static NSString *MyIdentifier = @"MyIdentifier";

	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
	if (cell == nil) {
		cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
	}

	NSDictionary *itemAtIndex = (NSDictionary *)[dataController getItem:indexPath.row];
	cell.text = [itemAtIndex objectForKey:@"title"];

	// Set up the cell
	return cell;
}

So you can see there, we are grabbing the dictionary from the array and then using the title key to grab out the title for each row at a certain index.

As always you can grab the source code here.