How to Display Cell Content in a Table View in Your iOS App

By Neal Goldstein, Dave Wilson

There may come a time when you need to display cell content in your iOS app. To display the cell content, your delegate is sent the tableView:cellForRowAtIndexPath message. Add this method to DestinationController.m.

- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"DestinationCell";
UITableViewCell *cell = [tableView
NSDictionary * destinationData = self.destinationsArray
NSAttributedString *attributedString =
[[NSAttributedString alloc]
attributes:@{ NSFontAttributeName : [UIFont
NSForegroundColorAttributeName: [UIColor
cell.textLabel.attributedText = attributedString;
return cell;

You see that one of the first things you do is determine whether any cells that you can use are lying around. You may remember that although a Table view can display quite a few rows at a time on the iPad’s screen, the table itself can conceivably hold a lot more.

A large table can eat up a lot of memory, however, if you create cells for every row. Fortunately, Table views are designed to reuse cells. As a Table view’s cells scroll off the screen, they’re placed in a queue of cells available to be reused.

If the system runs low on memory, the Table view gets rid of the cells in the queue, but as long as it has some available memory for them, it holds on to them in case you want to use them again.

You create a string to use as a cell identifier to indicate what cell type you’re using:

static NSString *CellIdentifier = @"DestinationCell";

It is critical that the CellIdentifier and the Identifier field of the Prototype cell in Step 18 are the same. If they are not, you won’t get the transparent prototype cell you specified in the storyboard.

Table views support multiple cell types, which makes the identifier necessary. In this case, you need only one cell type, but sometimes you may want more than one to accommodate cells with different layouts and formats. For example, if only some cells should have a disclosure triangle, you would probably use two prototypes — one with and one without the disclosure triangle.

You ask the Table view for a specific reusable cell object by sending it a dequeueReusableCellWithIdentifier: message:

UITableViewCell *cell = [tableView   dequeueReusableCellWithIdentifier:CellIdentifier];

This determines whether any cells of the type you want are available. If no cells are lying around, this method will create a cell using the cell identifier that you specified. You now have a Table View cell that you can return to the Table view.

You have several choices on how to format the Table View cell. Although you’re going to be using UITableViewCellStyleDefault, you can choose from a number of different styles, listed as follows (the keywords in the Style pop-up menu in the Attributes tab of Interface Builder are shown in brackets):

  • UITableViewCellStyleDefault: Gives you a simple cell with a Text label (black and left-aligned) and an optional Image view. [Basic]

  • UITableViewCellStyleValue1: Gives you a cell with a left-aligned black Text label on the left side of the cell and a right-aligned Text label with smaller gray text on the right side. (The Settings app uses this style of cell.) [Right Detail]

  • UITableViewCellStyleValue2: Gives you a cell with a right-aligned blue Text label on the left side of the cell and a left-aligned black Text label on the right side of the cell. [Left Detail]

  • UITableViewCellStyleSubtitle: Gives you a cell with a left-aligned Text label across the top and a left-aligned Text label below it in smaller gray text. (The Music app uses cells in this style.) [Subtitle]

With the formatting out of the way, you then set the Label properties that you’re interested in.

You pluck out the name for each destination you’ve stored by accessing the DestinationName in each Destination dictionary. You do that by accessing the dictionary in the (saved) destinationsArray corresponding to the sections and row in indexPath, which contains the section and row information in a single object.

To get the row or the section out of an NSIndexPath, you just have to invoke its section method (indexPath.section) or its row method (indexPath.row), either of which returns an int:

NSDictionary * destinationData =   destinationsArray[indexPath.row];

Next, create an attributed string, which can manage both the character strings and attributes such as fonts, colors, and even kerning:

NSAttributedString *attributedString = [[NSAttributedString alloc]   initWithString:destinationData[@"Destination​Name"]   attributes:@{ NSFontAttributeName : [UIFont systemFontOfSize:17.0f],   NSForegroundColorAttributeName: [UIColor whiteColor]}];

Now, use this attributed string to format the cell’s text label:

cell.textLabel.attributedText = attributedString;

Finally, return the formatted cell with the text it needs to display in that row:

return cell;