skip to Main Content

I have an expandable table view cell with several rows, and I’d like to make it impossible to have multiple rows opened at the same time.

here’s my code so far :

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    dataSource[indexPath.row].isExpanded.toggle()
    questionsTableView.reloadRows(at: [indexPath], with: .automatic)
}

I tried multiple ways to achieve this, such as :

var selectedIndex = 0

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if dataSource[indexPath.row].isExpanded == false {
        if indexPath.row == selectedIndex {
            dataSource[indexPath.row].isExpanded.toggle()
        } else {
            dataSource[selectedIndex].isExpanded.toggle()
            dataSource[indexPath.row].isExpanded.toggle()
        }
    } else {
        dataSource[indexPath.row].isExpanded.toggle()
    }

    selectedIndex = indexPath.row
    dataSource[indexPath.row].isExpanded.toggle()
    questionsTableView.reloadRows(at: [indexPath], with: .automatic)
}

But this doesn’t work.
I just need a line of code that would make all the rows close right before the new one opens, or a way to check if the new row clicked is a new one, in which case it would close the row opened before. That’s what I tried to do here, but it doesn’t work.

I’m still a beginner, so if you can give me a detailed answer it’d help me a lot.

2

Answers


  1. There are many ways to approach expand/collapse cells, but…

    Assuming your func set(...) in your table view cell properly configures the cell for expanded or not, here is just one approach:

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        // toggle the isExpanded property of your data element
        //  for the just-selected row
        dataSource[indexPath.row].isExpanded.toggle()
        
        // loop through ALL elements of your data
        for i in 0..<dataSource.count {
            // if it is NOT the selected row
            if i != indexPath.row {
                // set isExpanded to false
                //  this will "close" any other row that is expanded
                dataSource[i].isExpanded = false
            }
        }
        
        // reload the talbe data
        tableView.reloadData()
        
    }
    
    Login or Signup to reply.
  2. There isn’t "a line of code" to do what you want. You need to design an app that implements the UI you have in mind.

    If you are sure that you only ever want one cell to expand, you may want to set up your model to have an Optional value expandedRow. In your cellForRowAt method, you’d check to see if it’s nil. If nil, you would not build any of your cells as expanded. If it had a non-nil value, you’d build the cell at that index in the expanded form and all others in the non-expanded form.

    I’d also say that when the user triggers the action to expand a cell, you’d remember the old value of expandedRow, change it, and then tell the table view to update both the old row (if any) and new expanded row.

    No, I don’t have a line of code to give you. You don’t show the model you use, or what you do with your isExpanded property.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search