41

For the iPhone, is it possible to configure a UITableView such that it will allow multiple-selection?

I've tried overriding -setSelected:animated: for each UITableViewCell, but trying to fudge the required behavior is tricky as it's difficult to separate the real unselections from the ones where the UITableView thinks I've unselected due to selection of another cell!

Hope someone can help!

Thanks,

Nick.

luvieere's user avatar

luvieere

37.6k20 gold badges134 silver badges185 bronze badges

asked Nov 21, 2008 at 6:57

Nick Cartwright's user avatar

40

Following property should work fine if you are developing app for iOS5.0+

self.tableView.allowsMultipleSelection = YES;

answered Apr 1, 2012 at 23:12

Hamdi's user avatar

2 Comments

@JonEasy not at the time when the question was asked.

38

The best way to do this would be to a checkmark per selected row.

You can do that by setting the accessoryType on the selected UITableViewCell instances to UITableViewCelAccessoryCheckmark.

To deselect the row, set it back to UITableViewCellAccessoryNone.

To enumerate which cells/rows were selected (say, upon clicking a button), simply iterate over the cells of the table looking for UITableViewCellAccessoryCheckmark. Or, manage some NSSet or the like in your table view delegate in the "did select" delegate methods.

Josh Brown's user avatar

Josh Brown

53.4k11 gold badges58 silver badges85 bronze badges

answered Nov 21, 2008 at 16:39

z8000's user avatar

z8000

3,6653 gold badges32 silver badges37 bronze badges

2 Comments

Iterating over the cells of the table isn't accurate since table cells are often recycled and reused as you scroll through your table.

25

Use the following code to set up the cell accesory types:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *thisCell = [tableView cellForRowAtIndexPath:indexPath];


    if (thisCell.accessoryType == UITableViewCellAccessoryNone) {
        thisCell.accessoryType = UITableViewCellAccessoryCheckmark;

    }else{
        thisCell.accessoryType = UITableViewCellAccessoryNone;

    }
}

- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {

//add your own code to set the cell accesory type.
return UITableViewCellAccessoryNone;
}

1 Comment

While compiling under iOS 4.x the following warning is received: WARNING: Using legacy cell layout due to delegate implementation of tableView:accessoryTypeForRowWithIndexPath: in <MyViewController: 0x6e4fca0>. Please remove your implementation of this method and set the cell properties accessoryType and/or editingAccessoryType to move to the new cell layout behavior. This method will no longer be called in a future release. FYI.

11

I backported allowsMultipleSelectionDuringEditing and allowsMultipleSelection from iOS5 to older iOS. You can fork it at https://github.com/ud7/UDTableView-allowsMultipleSelection

It's drop in replacement and only thing you need to do is change UITableView to UDTableView (in code or interface builder)

answered Dec 4, 2011 at 5:15

RolandasR's user avatar

RolandasR

3,0502 gold badges27 silver badges26 bronze badges

Comments

5

From the HIG:

Table views provide feedback when users select list items. Specifically, when an item can be selected, the row containing the item highlights briefly when a user selects it to show that the selection has been received. Then, an immediate action occurs: Either a new view is revealed or the row displays a checkmark to indicate that the item has been selected. The row never remains highlighted, because table views do not display a persistent selected state.

You'll need to roll your own multiple selection style, either with something like Mail, or using the checkmark accessory on your cells.

answered Nov 21, 2008 at 12:01

Ben Gottlieb's user avatar

Ben Gottlieb

85.5k22 gold badges180 silver badges173 bronze badges

Comments

5

Guys for multiple selection you just need

self.tableView.allowsMultipleSelection = YES;

on viewDidLoad and

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
    tableViewCell.accessoryView.hidden = NO; 
    // if you don't use custom image tableViewCell.accessoryType = UITableViewCellAccessoryCheckmark;
}

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
    tableViewCell.accessoryView.hidden = YES;
    // if you don't use custom image tableViewCell.accessoryType = UITableViewCellAccessoryNone;
}

answered Dec 11, 2012 at 20:31

Raphael Oliveira's user avatar

Comments

3

I was searching for the same issue and the answer of Bhavin Chitroda sovled it for me but with some addition to keep the check mark as it was while scrolling.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
        if ( [array indexOfObject:indexPath] == NSNotFound ) {
            [array addObject:indexPath];
            cell.accessoryType = UITableViewCellAccessoryCheckmark;
        } else {
            [array removeObject:indexPath];
            cell.accessoryType = UITableViewCellAccessoryNone;
        }

}

The addition:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
// Your code here
.
.
.
    if ( [array indexOfObject:indexPath] == NSNotFound ) {
        cell.accessoryType = UITableViewCellAccessoryNone;
    } else {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }

    return cell;

}

answered Jan 16, 2013 at 10:08

Omar Elgendy's user avatar

Comments

2

If you're trying to do something like Mail's multiple-select (to delete mail, for example), then you're probably going to have to manage all the selection yourself. Multiple row selection isn't something that's standard on the iPhone. Mail solves this by using checkmarks to indicate which rows have been selected.

answered Nov 21, 2008 at 11:46

August's user avatar

August

12.2k3 gold badges32 silver badges30 bronze badges

Comments

2

blue highlighted row as an indicator of whether a row is selected is actually discouraged according to the HIG page 121. Checkmarks will do the trick.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    int selectedRow = indexPath.row;
    cout << "selected Row: " << selectedRow << endl;
    UITableViewCell *indexPathForCell = [tableView cellForRowAtIndexPath:indexPath];
    if (indexPathForCell.accessoryType == UITableViewCellAccessoryNone) {
        indexPathForCell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        indexPathForCell.accessoryType = UITableViewCellAccessoryNone;
    }

}

then add your arraying or how ever you wish to store the data of which were selected.

answered Feb 29, 2012 at 19:01

John Riselvato's user avatar

Comments

1

Note: This does not work in iOS 4+. This is a private, undocumented constant. Do not use it.

If you are not planning to submit your app to the App Store, you can invoke multi-row edit mode by implementing the following method in your UITableViewController delegate:

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 3; // Undocumented constant
}

answered Aug 6, 2010 at 21:30

titaniumdecoy's user avatar

titaniumdecoy

19.4k17 gold badges101 silver badges137 bronze badges

4 Comments

This works beautifully! Why oh why isn't this documented and allowed?!! Has anyone gotten an app approved with this in it? Not calling any undocumented methods... ?

Yeah what a bummer that this is still a private API. So SO useful.

apparently it is not anymore on 4.x---

To clarify: this doesn't seem to work anymore under iOS4 from my testing (I wasn't sure if Digital Robot was saying that it wasn't private or had been disabled)

0

Tested with iOS4.3 - 6.0

-(void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {

    if ([controller.searchResultsTableView respondsToSelector:@selector(allowsMultipleSelectionDuringEditing)]) {
        controller.searchResultsTableView.allowsMultipleSelectionDuringEditing = YES;
    }
    else {
        controller.searchResultsTableView.allowsSelectionDuringEditing = YES;
    }
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewCellAccessoryCheckmark;
}

answered Nov 12, 2012 at 10:52

Adriana's user avatar

Adriana

80611 silver badges36 bronze badges

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.