iPhone App displaying table list

Lesson 4. This lesson will look at how to create tables on your View and give the user sufficient control to delete and move entries around. It will look at creating multiple tables so that a user can drill down to some information displayed on a second view.


This lesson will look at how to create tables on your View and give the user sufficient control to delete and move entries around. It will look at creating multiple tables so that a user can drill down to some information displayed on a second view.

For those of you following the series, in order to demonstrate table views we will leave our previous project alone and start with a new project in XCode. So here goes…

In XCode Create New Product and select the Navigation-based Application. As before select Build and Run to see what the template gives you. You should see a list view.

Screen shot 2009-10-22 at 20.07.27

Within your Classes you will see RootViewController files (.m and .h) and your AppDelegate files (Your App Name>AppDelegate.m and .h). We will look at the usage of the AppDelegate file in a later tutorial. It is not required for what we want to achieve today. For this tutorial we will work on the RootViewController.m.

Sectioning Tables

Let us first of all see how we can change the look of the table. Within the rootViewController code you will see the following:-

– (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}

// Customize the number of rows in the table view.
– (
NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 0;
}

The first function sets the number of sections to be just one. The second sets the number of rows in each section to be 0. Change these to say 2 and 3 respectively and Build and Run to see the affect.

You should see no change. Although you have set the number of sections to be two and the rows to be three the style of the table has not been altered and there are no values in the table for you to be able to see the change. If you open the RootViewController.xib file and open the Inspector you will see from the Table Attributes on the view that the style is Plain. Switch it to Grouped.

Screen shot 2009-10-22 at 20.16.58

Save the change and then Build and Run again. You should now see a different table layout on the simulator.

Screen shot 2009-10-22 at 20.16.42

Changing the grouping and the number of rows and sections allows you to customise the layout of your table as required to create a better user interface.

Now lets add a header for each section. Within RootViewController.m below the number of sections we can add the following to create the section headers.

– (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSString* secHeader = @””;

if (section == 0)
{
secHeader =
@”section header1″;
}
else if (section == 1)
{
secHeader =
@”section header2″;
}
return secHeader;
}

We could have written a switch statement or not introduced secHeader at all. The preferred style of coding is down to each individual. As always
Build and Run to check the effect is as expected.

Screen shot 2009-10-23 at 11.53.15


Now lets put some data into the individual cells.

Within RootViewController.m there is a function to // Customize the appearance of table view cells.

// Customize the appearance of table view cells.
– (
UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @”Cell”;

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[
UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}

// Configure the cell.
cell.textLabel.text = [[NSString alloc] initWithFormat:@”section %i Cell %i”,indexPath.section,indexPath.row];

return cell;
}

The
cellForRowAtIndexPath method is called by tableView for each cell that the table needs to display. This code is automatically created for us by XCode when we create a navigation based application.

TableViewExplanation

We have set the cell textLabel to display the section and cell number as shown above in bold.

This will give the following on Build and Run.

Screen shot 2009-10-23 at 12.31.36

The section of code :-

static NSString *CellIdentifier = @”Cell”;

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[
UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}

instantiates a new ‘cell’ instance or re-uses a previous one. We will examine this more thoroughly in a later lesson.

Editing Table Views

We will now look at allowing the user to edit the table. However to demonstrate this functionality we will first return the view to a single section of multiple cells.

Within RootViewController.m set the number of sections back to 1 and the number of rows to say 20. Of course Build and Run to make sure it is as expected.

Within RootViewController.m locate the function – (void)viewDidLoad where it says // Uncomment the following line to display an Edit button in the navigation bar for this view controller.and do as it says. Make sure you uncomment the function and not just the line.

This should display the Edit button on the view.

Screen shot 2009-10-23 at 12.48.39

However if you select Edit and then attempt to delete a particular cell you should see that it doesn’t do anything. This is because we have fixed the number of rows within the section. It cannot reduce the number of rows to 19 when we have coded it to say there are 20. We therefore need to change the code to allow for a variable number of rows in accordance with how many are deleted.

Create a variable within RootViewController.h

@interface RootViewController : UITableViewController
{
int numberOfRows;
}

@end

Back in
RootViewController.m set a start value for the numberOfRows.

– (void)viewDidLoad {
[
super viewDidLoad];

numberOfRows = 20;

Then where you // Customize the number of rows in the table view. Set it to
return numberOfRows;

Locate the function to // Override to support editing the table view. Uncomment it and
// Delete the row from the data source. As follows:-


if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Delete the row from the data source.
numberOfRows–;
[
tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}

You should find the Edit and Delete functions work now.

Screen shot 2009-10-23 at 13.08.20

Screen shot 2009-10-27 at 11.40.43

Screen shot 2009-10-27 at 11.41.13

As can be seen above I have deleted cell 4. However the view shows two cells labelled cell 8. If I were to scroll down the screen and back again the cells would all be renumbered to show no gaps. There would only be 19 cells listed because 1 has gone, but there is no record of it being cell 4 that I deleted. Initially the original cells 0-3 and 5-8 are not redrawn as they were already on the screen, but the new cell in the 9th position (remembering labelling starts at 0) is added.

Normally we would have a data model behind this view which would also have to be edited to remove a ‘cell’ of data. We will look at using this view with a data model in the next tutorial however for now we will just continue to look at manipulating the view a little.

If we now what to add the functionality to allow a user to rearrange the cells rather than delete them we need to locate that function within the code.

// Override to support rearranging the table view.
// Override to support conditional rearranging of the table view.

Ensuring they are not commented out. We also need to run a method on the cell to ensure reorder control can be seen. We do this before we perform the previous cell configuring as follows;

// Configure the cell.
cell.showsReorderControl = true;
cell.
textLabel.text = [[NSString alloc] initWithFormat:@”section %i Cell %i”,indexPath.section,indexPath.row];

return cell;
}

When you select edit and then grab rearrange symbol on the right of a cell you should find the cell can be moved up or down as shown below with cell 2.

Screen shot 2009-10-27 at 12.08.31

Creating Another View

Now lets look at giving the user the ability to drill down on a cell of data. To do this we first need to create a new ViewController.

Select Classes within XCode and right click to Add a New File

Screen shot 2009-10-27 at 11.52.29Screen shot 2009-10-27 at 11.52.46

Select a UIViewController template and give it an appropriate name.

Screen shot 2009-10-27 at 11.53.04

Now that we have our new view controller we need to enable it to be displayed. We want to show it when the user selects a table cell. To do this we use the method didSelectRowAtIndexPath which is provided for us automatically by XCode. We first add an import for our new view controller to the rootViewController.

#import “DetailViewController.h”

Now we can add code to the didSelectRowAtIndexPath method to push our new detail view controller to the top of the navigation controllers display stack.

// Override to support row selection in the table view.
– (
void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

// Navigation logic may go here — for example, create and push another view controller.
//Create our Detail view contoller and push its view on navigation controllers stack.

DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@”DetailViewController” bundle:nil];
[
self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController
release];
}

A good explanation of how the navigation controller works can be found in the apple developer text.

If we select TextView from the library for our detail view in the same way we set up our initial views in our first tutorial we will see the following

Screen shot 2009-10-22 at 21.46.31

If we
Build and Run the simulator will display the following when we ‘double click’ a single cell.

Screen shot 2009-10-22 at 21.46.55

However we cannot go back to the previous view because we have not given it a name. We have not said what it is we want to go back to. Previously we added the edit button in the navigation bar by uncommenting the code. We can also here add the title for the first screen by calling the title method on self.

// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.title = @”Tutorial List”;

Screen shot 2009-10-22 at 22.00.45

Now when we move to the detail screen we automatically have an option on the navigation bar to return to the fist screen, our table view.

Screen shot 2009-10-22 at 22.00.56

Next Tutorial

In the next tutorial we will look at creating a data model to sit behind the table view so there is persistent data.