Multiselect UITableView with limited selections
Multiselect UITableView with limited selections
Simple example of creating a multi-select UITableView, but allow only a limited number of selected cells.
Introduction
I wanted a multi-select table view but limit the number of selected cells. The “answers” on StackOverflow were quite awful – which is true > 50% of the time.
So here is a simple working example
How to
Add a table view to your storyboard. (I know, well duh). In the attributes editor choose multi select.
Set your viewcontroller to be the table datasource and delegate. You know, the usual.
In your view controller, do the usual datasource setup.
For the limiting functionality, you need to do this in the delegate.
In my viewcontroller, I added a variable – the limit. Then in the delegate’s willSelectRowAtIndexPath func I compared the current number of selected cells (tableView.indexPathsForSelectedRows) to the limit returning nil if it’s over the limit.
That’s it. None of the contortions you see on SO.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
extension ViewController : UITableViewDelegate { func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? { if let sr = tableView.indexPathsForSelectedRows { if sr.count == limit { let alertController = UIAlertController(title: "Oops", message: "You are limited to \(limit) selections", preferredStyle: .Alert) alertController.addAction(UIAlertAction(title: "OK", style: .Default, handler: {action in })) self.presentViewController(alertController, animated: true, completion: nil) return nil } } return indexPath } func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { print("selected \(intervalNames[indexPath.row])") if let cell = tableView.cellForRowAtIndexPath(indexPath) { if cell.selected { cell.accessoryType = .Checkmark } } if let sr = tableView.indexPathsForSelectedRows { print("didDeselectRowAtIndexPath selected rows:\(sr)") } } func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { print("deselected \(intervalNames[indexPath.row])") if let cell = tableView.cellForRowAtIndexPath(indexPath) { cell.accessoryType = .None } if let sr = tableView.indexPathsForSelectedRows { print("didDeselectRowAtIndexPath selected rows:\(sr)") } } } |
In the other delegate methods, I just add eye candy.
And when you go over the limit.
Summary
All you really need to do is done in the delegate’s willSelectRowAtIndexPath func.
Hi, my name is Alok.
I run you code this is perfectly run in your limited tableview example as project named.
But when i implemented to my project it does not work correctly.
Issue is: when i selecting a row the checkmark selected or appear. and if we again tap on different cell then the previous cell checkmark is disappered .
what i do please tell.
I already applied your copy paste code to my project but no fixed this issue.
Reread the steps you need to take in Interface Builder. It’s not just the code.