Here is one way to do this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } [cell.textLabel setText:[NSString stringWithFormat:@"Row %d", indexPath.row]]; NSIndexPath* selection = [tableView indexPathForSelectedRow]; if (selection && selection.row == indexPath.row) { cell.accessoryType = UITableViewCellAccessoryCheckmark; } else { cell.accessoryType = UITableViewCellAccessoryNone; }
Remember that each cell in the table view is actually the same object that is reused. If you do not set the type of accessory every time cellForRowAtIndexPath is called, when new cells scroll to the screen, they all have the same accessory.
Multiple choice
For multiple choices, this is a little trickier.
Your first option: Undocumented API
Please note that this only works in table editing mode. Set the editing style of each cell for the undocumented UITableViewCellEditingStyleMultiSelect. Once you do this, you can get a view of the table view through the undocumented UITableView element: indexPathsForSelectedRows. This should return an array of selected cells.
You can expose this bit of functionality by placing it in the header:
enum { UITableViewCellEditingStyleMultiSelect = 3, }; @interface UITableView (undocumented) - (NSArray *)indexPathsForSelectedRows; @end
Then set the editing style for each cell as follows:
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewCellEditingStyleMultiSelect; }
When the table is in edit mode, you will see controls with multiple selections in your cells.
To view other undocumented APIs, you can use the nm command line utility as follows:
nm /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework/UIKit
The second option: manage your choice yourself
Your subclass of UITableView has an array that indicates which cells are selected. Then in cellForRowAtIndexPath, adjust the appearance of the cell using this array. Your didSelectRowAtIndexPath method should look something like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if ([tableView indexPathIsSelected:indexPath]) { [tableView removeIndexPathFromSelection:indexPath]; } else { [tableView addIndexPathToSelection:indexPath]; }
This assumes you are creating the indexPathIsSelected, removeIndexPathFromSelection, and addIndexPathToSelection methods in a subclass of UITableView. These methods should do exactly what their names mean: Add, delete, and check the index paths in the array. If you enable this option, you will not need the didDeselectRowAtIndexPath implementation.