iOS Tutorial: Basics of Table Views and Prototype Cells in Storyboards

In this tutorial, we’ll go over the basics of populating tableviews with data, and using the prototype cells introduced in iOS 5. Many of the samples online have very complicated navigation controller code. Instead, we want to just do the very basics of a UITableView and UITableViewCell. No nav bar, no master/detail navigation. We’re also not going to try to tackle Core Data here. We’re also not worried about saving our changes. We’re just trying to understand tables and cells.

First, we have two projects to download, the starter project, and the completed project. In the starter project, we’ve made a new project, added a Table View Controller in our storyboard, and deleted the View Controller. We also have deleted the ViewController.h/.m set that is made automatically, and created a new file, calling it RootViewController, which is a UITableViewController. We’ve also hooked this new file set to our Table View Controller in our storyboard.

Becoming a Delegate

The first step is to work with the UITableViewController, so that when the table view is being created, we populate it with data. We also want to keep the data in sync with what’s in the table. This means we sign up for two protocols in RootViewController.h:

@interface RootViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource>

 

Creating Data

For this tutorial, we’re just going to use an array. In a real project, it’s typical that you would connect to a web service and grab a data structure, like XML or JSON. Declare an array in RootViewController.h:

@property (strong, nonatomic) NSMutableArray *maTheData;

 

Now let’s implement it in RootViewController.m, we’ll synthesis our array, and build it when we load:

@implementation RootViewController@synthesize maTheData;

– (void)viewDidLoad
{
[super viewDidLoad];
if (!maTheData) {
maTheData = [[NSMutableArray alloc] initWithObjects:@”Comets”, @”Asteroids”, @”Moons”, nil];
}
}

 

Implementing Table View Delegate Methods

Now we have some work to do to populate our table. The way we do this is by setting data at different parts of the table as it is built row by row. First, we need to identify the number of sections the table needs. If this is zero, nothing will ever appear. In our case, it’s just one.

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

 

Next, we need to identify the number of rows we need in the section, which is the number of items in the array.

– (NSInteger)tableView: (UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
return [maTheData count];
}

 

Storyboard Connections

Time to go to the storyboard, and select the Table View. Ctrl-drag back to the RootViewController. We want to connect it back to the controller to ensure both the delegate AND the datasource are connected to the controller class. This ensures the delegate calls will fire, and the data will we synced. If you skip this step, you won’t see anything in your cells.

Prototype Cells

Cell designs that are reused, are very performant, as opposed to cells that are completely different, row to row. Many apps use the standard cell types, basic, right detail, left detail, subtitle. But you may have an app with custom cells with more information or purpose. This is where prototype cells have make the process a lot easier than in the past. Prototype cells in a storyboard allow you to create custom cells quickly. Just drag the components you want on your cell.

It is incredibly important to set your identifier for the cells, because when you get to the delegate methods, you need to indicate the cells’ class. This provides the access to put the data on the cell itself. From the storyboard, select the one table view cell, which is a child of the table view, and go to the Attributes Inspector. Under Identifier, type “tvcItems”.

Select the cell, still in the Attributes Inspector. The first item is Style. Choose Basic. Now the cell has a label that’s been added automatically. Farther down in the view section is Tag, type “100.” The number does not matter, a much as the fact that each object on the cell should have a unique tag. If you don’t use the tag, the data will not appear later.

Populating Cells

Using the combination of the cell identifier and the tag, we will have full access to deliver the data to the cell. Back to RootViewController.m, add:

– (UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@”tvcItems”];
UILabel *lblName = (UILabel *)[cell viewWithTag:100];
[lblName setText:[maTheData objectAtIndex:[indexPath row]]];
return cell;
}

 

Run the project in the simulator, and you should see a simple table view with our array data.

Custom Cells

Whether you use one of the custom table view cell style types or go custom, the process is the same. However, with custom, you must drag all the objects you want on the cell manually. Go to the storyboard and select the cell. Change the style to Custom. The first thing you’ll notice is our label is gone. Grab one and drag it onto the cell, and set its Tag to 100. Now grab a Round Rect Button and drag it onto the cell, and set it’s Tag to 200. The Tag is in the View section, so you will have to scroll down a bit to find it, but it’s there. You may want to manually make them wider, so the text will fit easily.

Now go back to RootViewController.m, and add to the cellForRowAtIndexPath method to:

– (UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@”tvcItems”];
UILabel *lblName = (UILabel *)[cell viewWithTag:100];
[lblName setText:[maTheData objectAtIndex:[indexPath row]]];
UIButton *btnName = (UIButton *)[cell viewWithTag:200];
[btnName setTitle:[maTheData objectAtIndex:[indexPath row]] forState:UIControlStateNormal];
return cell;
}

 

Run it again in the simulator, and the buttons should have the same text from the array. While this may not seem terribly useful, it shows the basics of customization. A real project would typically have complex sets of data, including images and multiple labels. For each object type, drag it, tag it, make a local method variable of the object type, and set the data to it.

Conclusion

The addition of storyboards and prototype cells has made the old way of populating tables much easier than before. The process is to become a delegate, have some data available, set the delegate and datasource from the table to the controller, set the identifier for the cell, set the tags of the cell objects, and implement the delegate methods.

Category(s): iOS

Comments are closed.