Abhishek Harsha
Abhishek Harsha

Reputation: 257

Single and Multiple Selection in same tableView

I have a tableView which has two different sections, one for single selection and one more for multiple selection. I also built two different custom cells for the same. I am able to get multiple selection right,but not the single selection.

I am using the override provided setSelected by the tableView Cell for both single and multiple Selection.

override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        if selected {
            //make label red
            }
        } else {
            //make label white
        }

    }

However, the problem which i am facing is that when I click on multipleSelection section's cell, the setSelected ovveride of my singleSelectionCell gets called and it marks the label white. If a cell is already selected in singleSelection I need to keep it that way.

I looked at this answer but I am not sure how to go about this. https://stackoverflow.com/a/32857181/4863339

can someone please help me in rectifying this problem?

Upvotes: 2

Views: 5948

Answers (1)

Nirav D
Nirav D

Reputation: 72410

To do what you want you need to maintain the state of selection of your cell, for single selection Section declare one instance property of type IndexPath? and for multiple selection section declare one instance property of type [IndexPath]. After that compare this property in cellForRowAt method and change its value in didSelectRowAt method.

Edit: With Custom Object you can try like this way, With your sectionItem Class create one property selected of type Bool and use that to select multiple or single item

SO your class should be look like this.

class Section {
    var isMultiple: Bool
    var title: String
    var items: [Item]

    init(isMultiple: Bool, title: String, items: [Item]) {
        self.isMultiple = isMultiple
        self.title = title
        self.items = items
    }
}

class Item {
    var id: Int
    var name: String
    //To maintain selected state
    var selected: Bool = false

    init(id: Int, name: String) {
        self.id = id
        self.name = name
    }
}

Now with cellForRowAt and didSelectRowAt it should goes like this way.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
    let item = sections[indexPath.section].items[indexPath.row]
    if sections[indexPath.section].isMultiple {
        //For multiple selection
        if item.selected {
            cell.accessoryType = .checkmark //Or make label red
        }
        else {
            cell.accessoryType = .none //Or make label white
        }
    }
    else {
        //For single selection
        if item.selected {
            cell.accessoryType = .checkmark //Or make label red
        }
        else {
            cell.accessoryType = .none //Or make label white
        }
    }
    cell.textLabel?.text = sections[indexPath.section].items[indexPath.row].name

    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if sections[indexPath.section].isMultiple {
        //For multiple selection
        let item = sections[indexPath.section].items[indexPath.row]
        item.selected = !item.selected
        sections[indexPath.section].items[indexPath.row] = item
        self.tableView.reloadRows(at: [indexPath], with: .automatic)
    }
    else {
        //For multiple selection
        let items = sections[indexPath.section].items

        if let selectedItemIndex = items.indices.first(where: { items[$0].selected }) {
            sections[indexPath.section].items[selectedItemIndex].selected = false
            if selectedItemIndex != indexPath.row {
                sections[indexPath.section].items[indexPath.row].selected = true
            }
        }
        else {
            sections[indexPath.section].items[indexPath.row].selected = true
        }
        self.tableView.reloadSections([indexPath.section], with: .automatic)
    }
}

Upvotes: 1

Related Questions