Programming the iPhone : Tables and Embedded Controls

8/7/2012 3:51:07 PM
A table in Cocoa Touch represents a vertical list of items, with each item assigned to a cell or row in the table. If the list of items is multi-dimensional, such as a list of email messages in the Mail application, each table cell should display a succinct summary, label, or other high-level indication of the object assigned to the cell. Users can get additional information for each row by tapping the row. When a user taps the row, an event is sent to the delegate of the table, which is an object that conforms to the UITableViewDelegate protocol. This protocol defines methods for handling interaction with cells. A table delegate defines the methods it wishes to handle, and the table controller automatically handles the communication between the user interface and the delegate. (The availability of free implementations of design patterns like the delegate pattern is one of the benefits that Cocoa Touch controller classes offer developers.)

You can embed UIControl instances in table cells to add functionality within the context of a single row in your dataset. For example, users will often need to delete a record using a button, as with the Mail application, or change the order of rows in a table. The table delegate protocol, UITableViewDelegate, allows developers to handle user-initiated edits like reordering, deletion, and insertion of new rows into the table.

The controls you use in table cells should be chosen with attention to the interactive nature of the tables and cells themselves. Most tables are embedded in a scrolling view that responds to gestures with movement along the y-axis. In those cases, it would be difficult to present users with an embedded control that also responds to gestures along the y-axis. Tables that act as views for navigation controllers and allow users to drill down through a hierarchical dataset already handle taps.

Adding controls to table cells is simple. There are three approaches to developing custom table cells:

  • Create an instance of UITableViewCell and set its public properties, using the default object and layout with custom content.

  • Create an instance of UITableViewCell and customize it using public properties and methods for managing subviews. This can include adding subviews to the contentView of the cell, setting the accessoryView appropriately, adding an icon or image to the left side of the cell using the imageView property, and manipulating the visual characteristics such as background color and text properties. In most cases, a standard UITableViewCell is an appropriate starting point because it provides customized consistency in the user experience.

  • Subclass UITableViewCell with overrides for initialization, layout, and event handling, and add any functionality desired.

The simplest option is to create an instance of UITableViewCell and customize it using properties. Working with standard cell properties minimizes the amount of code required for customization, which in turn limits the risk of bugs. Users benefit from standard cells because familiarity speeds the learning curve for new users.

Adding subviews to a standard UITableViewCell is slightly more complex. Developers must manage the layout of subviews and support resizing and repositioning subviews to support rotation. In exchange, more customization is possible.

The most complex and flexible option is to subclass UITableViewCell. Developers can override the core functionality of a cell to render complex artwork or manage touch events in novel ways.

Standard table view cells include three subviews that display content to users. On the left side of each cell is a view called imageView. The center and majority of the cell is occupied by a view that displays the main cell content, sensibly called the contentView. To the right of the contentView is a subview that can display standard indicators such as a checkmark, chevron, custom graphic, and even controls. The view for accessories is called the accessoryView.

1. Passive Indicators

The disclosure indicator is a familiar control for diving deeper into a stack of UINavigationController instances from within a UITableView. The disclosure indicator looks like a chevron and shows that more information is available for a row. You can set the indicator type for a cell by setting the accessoryType property of the UITableCell instance to UITableViewCellAccessoryDisclosureIndicator:

- (UITableViewCell *)tableView:(UITableView *)tableView
		cellForRowAtIndexPath:(NSIndexPath *)indexPath
			static NSString *CellIdentifier = @"OMG_Its_a_Cell";

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

			cell.text = [nodes objectAtIndex:indexPath.row];

			return cell;

You can display a checkmark as an accessory by assigning the UITableViewCellAcces⁠soryCheckmark constant to accessoryType:

cell.accessoryType = UITableViewCellAccessoryCheckmark;

Assigning a custom image to an accessory view is nearly as simple:

cell.accessoryView = [[[UIImageView alloc] initWithImage:myImage] autorelease];


2. Active Indicators and Control Accessories

Developers can assign any UIView to the accessoryView property, including controls like sliders, buttons, and switches.

If the additional detail for the object represented by the cell consists of configuration options, or if the cell has multiple subviews that track touches independently, you can use a detail disclosure button by assigning UITableViewCellAccessoryDetailDisclosur⁠eButton to the accessoryType property of the cell:

- (UITableViewCell *)tableView:(UITableView *)tableView
		cellForRowAtIndexPath:(NSIndexPath *)indexPath
			static NSString *CellIdentifier = @"OMG_Its_a_Cell";

			UITableViewCell *cell = [tableView
			if (cell == nil) {
				cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
					reuseIdentifier:CellIdentifier] autorelease];
				cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;

			cell.text = [nodes objectAtIndex:indexPath.row];

			return cell;

Disclosure buttons handle user interaction separately from the cells in which they are embedded. To respond to user interaction for a disclosure button in an accessoryView, define a tableView:accessoryButtonTappedForRowWithIndexPath: method in your table view’s delegate:

- (void)tableView:(UITableView *)tableView
accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
	// Forward the message to the tableView:didSelectRowAtIndexPath:
	// method. You can do anything you want here. You may want to
	// treat disclosure buttons separately from the cell, showing
	// a configuration screen instead of a detail screen, for example.
	[self tableView:tableView didSelectRowAtIndexPath:indexPath];

Disclosure buttons can also be used outside of tables. The simple clarity and ubiquity of disclosure buttons across applications enable users to understand that more information is available for the selected context:

- (id)initWithFrame:(CGRect)frame
			if (self = [super initWithFrame:frame]) {
				self.backgroundColor = [UIColor clearColor];

				// Add a disclosure detail button to the view.
				disclosure = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
				[self addSubview:disclosure]; = CGPointMake(270.0, 20.0);
				[disclosure addTarget:self action:@selector(disclose:)

				// Other setup here.
			return self;

You can use custom buttons or other controls as accessories by adding them to the accessoryView. If you create a custom control for your accessoryView, you will need to use the target-action mechanism to capture the events generated by user interaction.
  •  Programming the iPhone : Scrolling Controls
  •  BlackBerry Java Application Development : Networking - Testing for availability of transports
  •  XNA Game Studio 4.0 : Multitouch Input For Windows Phones (part 2) - Displaying GestureSample Data
  •  XNA Game Studio 4.0 : Multitouch Input For Windows Phones (part 1)
  •  Motorola Motoluxe
  •  Apple's Undiscovered Country : The future of the iPhone
  •  Apple's Undiscovered Country : The Future Of The Ipad
  •  Programming the iPhone : Standard Control Types (part 6) - Segmented Controls
  •  Programming the iPhone : Standard Control Types (part 5) - Search Bars
  •  Programming the iPhone : Standard Control Types (part 4) - Tables and Pickers
  •  Programming the iPhone : Standard Control Types (part 3) - Sliders
  •  Programming the iPhone : Standard Control Types (part 2) - Modal Buttons
  •  Programming the iPhone : Standard Control Types (part 1) - Buttons
  •  Sony Introduced 3 New Phones In Xperia Series: Tipo, Miro And Ion
  •  Samsung Galaxy SIII And HTC One X: A Detailed And Thorough Comparison
  •  In Control
  •  BlackBerry Virtual Keyboard: The Development Through Each Appliance
  •  3D Phone – Why Is LG Optimus 3D Max P725 The Best Choice, Still?
  •  XNA Game Studio 4.0 : Xbox 360 Gamepad (part 2) - Moving Sprites Based on Gamepad Input
  •  XNA Game Studio 4.0 : Xbox 360 Gamepad (part 1) - Reading Gamepad State
    Top 10
    HP ElitePad 900 - A Well-Built Business Tablet
    Huawei MediaPad 7 Lite Android Tablet
    Best New App-Ons – August 2013
    How To See Through Website Lies
    17 Killer Mac Apps Under $20 (Part 5)
    17 Killer Mac Apps Under $20 (Part 4)
    17 Killer Mac Apps Under $20 (Part 3)
    17 Killer Mac Apps Under $20 (Part 2)
    17 Killer Mac Apps Under $20 (Part 1)
    PC Specialist Fusion Z11 - Black Midi Tower Window Gaming Case
    Most View
    Intel In Flux: Are We Heading To A Socket-Less Future? (Part 1)
    Handy Hints And Tips
    Master The New Calendar
    Toshiba Camileo S40 - A Small Pistol-Grip Camcorder
    USB DACs Super Test: PC + DAC = HI-FI (Part 5)
    Microsoft ASP.NET 4 : Dynamic Data Details
    ASRock FM2A85X Extreme6 Socket FM2 Mainboard Review (Part 7)
    Lenovo Thinkpad Carbon Touch Ultrabook Review (Part 2)
    People, Always The Weakest Link
    Sondek LP 12 - The One And Only (Part 1)