Home > Software engineering >  Swift 5: Reload a UITableView while preserving selections and style
Swift 5: Reload a UITableView while preserving selections and style

Time:05-04

I have a tableview with 3 cells, I need to update my tableview, at the moment I am using reloadData, but I would like to save the cell selection when the tableview is closed and then reopened, I would also like to save the style of that cell, that is the background color, the label color. This is my code:

extension UITableView {
func reloadDataSavingSelections() {
    let selectedRows = indexPathsForSelectedRows

    reloadData()

    if let selectedRow = selectedRows {
        for indexPath in selectedRow {
            selectRow(at: indexPath, animated: false, scrollPosition: .none)
        }
    }
}

class MainViewController: UIViewController {

override func viewWillAppear(_ animated: Bool) {
        _view.tableView.reloadDataSavingSelections()
    }
}

CodePudding user response:

You need to store the selected values because indexPathsForSelectedRows will be cleaned after reloadData(). You can use a Set to store selected index paths, for example:

    class MainViewController: UIViewController, UITableViewDataSource {

    var selectedIndexPaths = Set<IndexPath>()
    
    override func viewWillAppear(_ animated: Bool) {
        _view.tableView.reloadDataSavingSelections()
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        if selectedIndexPaths.contains(indexPath) {
            // you can setup a selection style here
        }
    }
}

CodePudding user response:

I believe you can implement tableView(_:willDisplay:forRowAt:) method of UITableViewDelegate to set selection:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // TODO: store selected item

    tableView.selectRow(at: indexPath, animated: true, scrollPosition: false)
}

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    let shouldSelect: Bool = // TODO: Check if item is selected

    if shouldSelect {
        cell.setSelected(true, animated: false)
    }
}

Assuming you have a data source with unique identifiers, you can store and match against underlying data model rather than index paths to determine the selected cell.

  • Related