Introduction
At Nixwire, I’m using the Three20 Project as a foundational framework for an application where I needed to create a multiple-selection UITableView, so that I could perform an operation on all table rows selected by the user. The UITableView control does not support multiple-row selection without custom programming. Matt Gallagher provides a helpful example on how to create a multi-select table on his Cocoa with Love blog. Using Matt Gallagher’s example as a starting point, I made the multi-select control work in the context of the Three20 framework, and share my learnings here.
The Three20 Project was created by Joe Hewitt of Facebook. The components in Three20 were originally built as part of the Facebook iPhone application, then Joe Hewitt made the components generic and open-sourced the framework. Three20, currently characterized as “alpha quality” by the project owner, provides an excellent set of reusable UI and plumbing components for iPhone applications. Being in an alpha development state, documentation is scant and there can be a learning curve, but the value provided by the framework makes it worth the effort to learn. Components provided by the Three20 framework include:
- A photo viewer control that behaves similar to Apple’s Photos app
- A message composer that behaves similar to Apple’s Mail app
- TableViewControllers that are able to load their content from the internet
- URL-based intra-app navigation, allowing URL binding to resources within your application
- Persistent state on UI controls
Solution detail
Controller setup
First, we need to set up the controller. Our controller, NXWMultiselectTableViewController, inherits from TTTableViewController, and is registered with the Three20 framework’s NavigationCenter by associating it with the URL “tt://nxwMultiselect”.
TTNavigationCenter* nav = [TTNavigationCenter defaultCenter]; nav.mainViewController = self.navigationController; nav.delegate = self; nav.urlSchemes = [NSArray arrayWithObject:@"tt"]; ... [nav addView:@"nxwMultiselect" controller:[NXWMultiselectTableViewController class]];
Once the controller is mapped to the URL, any Three20 control can be configured to navigate to the controller’s view with click actions. For example, to navigate to our multiselect table from another table’s cell, you would set up the URL property on the cell’s TableField to the desired URL:
[[[TTTableField alloc] initWithText:@"Multiselect" url:@"tt://nxwMultiselect"] autorelease]
Then, when clicking on the table cell, the Three20 framework loads the appropriate controller by calling the loadView method on the controller. Sweet!
Sequence diagram for “checking” an item
Once the controller is loaded, the user may “check off” cells by tapping them. The sequence diagram below shows how the various classes interact to “check off” a multi-select table row while in edit mode.

Sequence diagram: Select table row to "check"
- User selects the row. The UITableView sends tableView:didSelectRowAtIndexPath: method call to the TableViewDelegate.
- TableViewDelegate adds index path to SectionedDataSource’s selectedIndexPaths array.
- TableViewDelegate sends tableView:prepareCell:forRowAtIndexPath: method call to the SectionedDataSource.
- DataSource prepares the TTImageTableField’s defaultImage property to the checked PNG image.
- DataSource sends a setNeedsLayout method call to the TableFieldCell, which prepares the cell for rendering.
Items to note
- Minimal drawing code. Aside from a few lines of code in the TableFieldCell’s layoutSubviews method, there is no code required to draw the cell; the TTImageTableField Three20 class takes care of the drawing.
- Customizable data source. The data source used in this example uses a hard-coded array of names; in order to display real data, you would need to set up the data source with the appropriate data through the TableViewController’s createDataSource method.
- URL-based navigation. After binding the controller to the desired URL in the TTNavigationCenter, the control can be accessed by URL within the application.
- Searchable table. The source includes the ability to filter the table results by typing one character at a time. While this capability is beyond what I’ll cover in this post, it’s worth studying my example to see how search is implemented. Pay attention to the TTSearchBar that is set up in the TableViewController’s loadView method, as well as the SectionedDataSource’s tableView:search: method and rebuildItems method.
Screenshots of the solution
TTTableView in non-edit mode with no items selected:

TTTableView in non-edit mode
TTTableView with some items selected:

TTTableView with items selected
Confirmation of items selected:

Confirmation of items selected
Source code
Source code for this example is available here. The example requires the current version of the Three20 framework (as of 11 May 2009).
![Reblog this post [with Zemanta]](http://img.zemanta.com/reblog_e.png?x-id=94e39be9-9c89-4b45-b64e-3d6006317a60)
