IOS 5 How To Create and Populate UITableViews | iPhone | iPad | iPod Touch
85
One of most powerful elements for capturing, organizing and presenting data in IOS 5 and Objective-C is the UITableView and UITableViewDelegate. Both are part of the Cocoa Touch Layer in the IOS 5 SDK.
This tutorial will teach you how.
Create a Project
To begin, create a Single-View IOS 5 Project. Name it whatever you want. For the purpose of this tutorial, I named mine FirstTableProject (Figure 1). Once the project has finished loading open the Storyboard and drag a UITableView unto the Canvas. Switch to the Attributes Inspector and provide a Title for the View Controller and an Identifier. Also check (enable) the “Is Initial View Controller” property.
Next select the Prototype Cell and change the style to “Subtitle” in the Attribute Inspector. also provide an identifier. You will use this identifier later in the implementation file. In the Accessory and Editing Acc. fields, select the “Disclosure Indicator”.
Oh yes, you can select and delete the Single View Controller that the template created because we won’t it for this tutorial. You can also delete the header and implementation files that are associated with the Single View Controller.
Create a Table View Controller
Create a new View Controller and select the “UIViewController Subclass” from the wizard. In the next screen or document, provide a name to your class and the select the UITableViewController subclass. Also disable the xib file property and the iPad target property. Complete the creation of the class.
Before moving on to the next section, re open the Storyboard and select the Table View and switch to the Identify Inspector and change the Custom class to the new UITableViewController class that you just created. This will associate the Table View Controller in the Storyboard with the UITableViewController class.
Create a Data Class
Create a new Objective-C class and name it Author. Add three properties: name, title and genre
…
#import <Foundation/Foundation.h>
@interface Author : NSObject{
NSString *name;
NSString *title;
NSString *genre;
}
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *title;
@property(nonatomic,copy) NSString *genre;
@end
...
Next, as usual, create the setter or accessor properties in the implementation file. Continue with the implementaiton by opening the UITableViewController, AuthorVC, and add a NsMutableArray variable and property.
#import <UIKit/UIKit.h>
@interface AuthorVC : UITableViewController{
NSMutableArray *theauthors;
}
@property(nonatomic,retain) NSMutableArray *theauthors;
@end
Finally open the implementation file and create the accessor method for the NSMutableArray. Next, in the viewDidLoad method, above the [super viewDidLoad], initialize the NSMutableArray variable, theauthors, with a capacity of 5 elements (note you can add as many rows as you like).
Create an Author object, providing values for the name, title and genre properties. Next add the item to the NSMutableArray using the addObject property (see code below). Repeat the process as many times as you like.
theauthors = [NSMutableArray arrayWithCapacity:5];
Author *anAuthor = [[Author alloc]init];
anAuthor.name = @"Clive Cussler";
anAuthor.title = @"Sahara";
anAuthor.genre = @"Action";
[theauthors addObject:anAuthor];
You could also use the records from a database, like SQLite, to populate the NSMutableArray. If you need instructions on how to create a database, check out my article: Tutorial on Creating an IOS 5 SQLite Database Application | IOS 5 | SQLite
A couple of more steps are required before we are finished. Scroll down to the “numberOfSectionsInTableView” and change the return value to 1.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
In the “numberOfRowsInSection” change the return value to the number of items in the theauthors NSMutableArray
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.theauthors count];
}
Finally in the “cellForRowIndexPath” method change the CellIdentifier value to the cell identifier, “AuthorsCell” or whatever you named yours. Next create an Author object and set it to the row index and add the values for name and title.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"AuthorsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Author *author = [self.theauthors objectAtIndex:indexPath.row];
cell.textLabel.text = author.name;
cell.detailTextLabel.text = author.title;
return cell;
}
That is it for the coding. All you need to do is run the app and test it.
App Output
Run the application and you should see the item(s) that were added to the NSMutableArray. (Figure 5).
Source Code
As usual, here is the source code for the various classes.
Author.h
//
// Author.h
// FirstTableProject
//
// Created by Kevin Languedoc on 12/5/11.
// Copyright (c) 2011 kCodebook. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Author : NSObject{
NSString *name;
NSString *title;
NSString *genre;
}
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *title;
@property(nonatomic,copy) NSString *genre;
@end
Author.m
// // Author.m // FirstTableProject // // Created by Kevin Languedoc on 12/5/11. // Copyright (c) 2011 kCodebook. All rights reserved. // #import "Author.h" @implementation Author @synthesize name; @synthesize title; @synthesize genre; @end
AuthorVC.h
//
// AuthorVC.h
// FirstTableProject
//
// Created by Kevin Languedoc on 12/5/11.
// Copyright (c) 2011 kCodebook. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface AuthorVC : UITableViewController{
NSMutableArray *theauthors;
}
@property(nonatomic,retain) NSMutableArray *theauthors;
@end
AuthorVC.m
//
// AuthorVC.m
// FirstTableProject
//
// Created by Kevin Languedoc on 12/5/11.
// Copyright (c) 2011 kCodebook. All rights reserved.
//
#import "AuthorVC.h"
#import "Author.h"
@implementation AuthorVC
@synthesize theauthors;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
theauthors = [NSMutableArray arrayWithCapacity:5];
Author *anAuthor = [[Author alloc]init];
anAuthor.name = @"Clive Cussler";
anAuthor.title = @"Sahara";
anAuthor.genre = @"Action";
[theauthors addObject:anAuthor];
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.theauthors count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"AuthorsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Author *author = [self.theauthors objectAtIndex:indexPath.row];
cell.textLabel.text = author.name;
cell.detailTextLabel.text = author.title;
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
@end
In Summary
The UITableView offers a lot of great functionality, which is out of scope for the current article but will be covered in subsequent articles. This article provided the basis for viewing items in the table and will be the basis on which we can build other functionality.
CommentsLoading...
That's brilliant, I really like the way you put your guides together, look forward to it :)
Hi,
I've followed this tutorial - I think exactly. It seems no matter what I try however, I'm getting this error.
https://img.skitch.com/20120413-jtpba3pgug1q5wjg6d
I've deleted and started from scratch, and scratched my head for hours now. The error seems so obscure with no real information.
Thanks.
The last thing i see it hit is the viewDidLoad method in the table controller. It doesn't hit any of the other methods implemented by that controller. I turned on the NSZombie mode and it's yelling at me inside of the main.m file - and when i look at the stack none of it resides within code i've toched.
On a completely separate note - I've looked into this error and from what other people say, the most obscure of things can cause it. Why such an obscure error in favor of more detailed ones?








Mark 3 months ago
Hey,
I've followed this article after looking at the sqlite one, I'm still unsure how to incorporate the sqlite tutorial into this so that data from the db is displayed in a tableview and the user can select a row to give further info.
I know you must be very busy but is there any chance you could do a tutorial for this? That would really help me out and be would greatly appreciated :)