UITableView Multiple Selection
Solution 1:
For multiple selection, add the line below in viewDidLoad()
tableView.allowsMultipleSelection = true
Configure each cell
after dequeuing (or initializing) it in tableView(_:cellForRowAt:)
let selectedIndexPaths = tableView.indexPathsForSelectedRows
let rowIsSelected = selectedIndexPaths != nil && selectedIndexPaths!.contains(indexPath)
cell.accessoryType = rowIsSelected ? .checkmark : .none
// cell.accessoryView.hidden = !rowIsSelected // if using a custom image
Update each cell when it's selected/deselected
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)!
cell.accessoryType = .checkmark
// cell.accessoryView.hidden = false // if using a custom image
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)!
cell.accessoryType = .none
// cell.accessoryView.hidden = true // if using a custom image
}
When you're done, get an array of all the selected rows
let selectedRows = tableView.indexPathsForSelectedRows
and get the selected data, where dataArray
maps to the rows of a table view with only 1 section
let selectedData = selectedRows?.map { dataArray[$0.row].ID }
Solution 2:
In your implementation of -tableView:didSelectRowAtIndexPath:
you would set the table view cell's accessoryType
property depending on its current value (so it would toggle on and off with multiple taps). For example:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)path {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:path];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
} else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
You could either maintain an array of selected states in addition to the cells' own accessory type state, or iterate over the cells in the table view querying for each one's state in order to read out the selected rows.
Solution 3:
@BrendanBreg implementation didn't worked for me. @RaphaelOliveira provided good solution, but when you scrolls your table down - wrong rows become selected (because UITableView
caches it's cells). So, I've slightly modified Raphael's solution:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
}
/*Here is modified part*/
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
/*
...
Your implementation stays here
we're just adding few lines to make sure
that only correct rows will be selected
*/
if([[tableView indexPathsForSelectedRows] containsObject:indexPath]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}