user3722523
user3722523

Reputation: 1800

UITableView - Multiple selection AND single selection

I have 2 sections in my UITableView.
I want the first section to allow multiple cell selection and the second section to allow only single selection.
I tried some code but didn't work very well.
Code in swift if possible. Thank you.

enter image description here

Upvotes: 9

Views: 9156

Answers (4)

Anand
Anand

Reputation: 5332

This is easily achievable in two lines as follows: (Swift 4)

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    if sectionAllowsMultipleSelection {
        if let indexPathsInSection = tableView.indexPathsForSelectedRows?.filter ({ $0.section == indexPath.section && $0.row != indexPath.row }) {
            for selectedPath in indexPathsInSection {
                tableView.deselectRow(at: selectedPath, animated: false)
            }
        }
    }
}

Upvotes: 2

AshWinee Dhakad
AshWinee Dhakad

Reputation: 681

You can simply try this. This solution works for me perfectly. Give it a try maybe worked for others...

Swift-4

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if indexPath.section == 0 {
        if let cell = tableView.cellForRow(at: indexPath) {
            cell.accessoryType = .checkmark
        }
    }
    else {
        if let cell = tableView.cellForRow(at: indexPath) {
            cell.accessoryType = .checkmark
        }
    }
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    if indexPath.section == 1 {
        if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
            cell.accessoryType = .none
        }
    }
}

Upvotes: 7

Caleb
Caleb

Reputation: 5626

If you want the selected row in section 2 to be the new selected row, this might work for you. Else, go with @NicolasMiari's answer.

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if indexPath.section == 1 {
        for i in 0..tableView.numberOfRowsInSection(indexPath.section) - 1 {
            let cell: UITableViewCell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: i, inSection: indexPath.section))!
            if (i == indexPath.row) {
                cell.accessoryType = .Checkmark
                cell.selected = false
            }
            else {
                cell.accessoryType = .None
            }
        }
    }
    else {
        //Do whatever for the first section
    }
}

Not very elegant, but hopefully it will give you an idea.

Upvotes: 0

Nicolas Miari
Nicolas Miari

Reputation: 16256

Perhaps you could implement the table view's delegate methods:

tableView(_:shouldHighlightRowAtIndexPath:)

and

tableView(_:didSelectRowAtIndexPath:)

...and determine (from indexPath.row and indexPath.section) if the relevant section supports single/multiple selection (this will depend on your data model's custom logic -e.g.: "Section 0 supports multiple selection but section 1 does not"), and if it only supports single selection, check whether there is already a row selected (by accessing tableView.indexPathsForSelectedRows).

If there is a selected row already, you can:

  1. Return false from tableView(_:shouldHighlightRowAtIndexPath:), and
  2. Do nothing (just return) from tableView(_:didSelectRowAtIndexPath:) (I'm not sure if this method is actually called when you return false from shouldHighlight..., so perhaps check it).

Upvotes: 4

Related Questions