Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swiping on a tableview is deselecting all selected rows trailingSwipeActionsConfigurationForRowAt

Recently implemented trailingSwipeActionsConfigurationForRowAt , where after swiping from right to left showing two options and its working fine. But the problem is when i select multiple rows or single row, after swiping the row/s they are getting deselected. Is there a way to keep the selection even after swiping?

Below is my code

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) ->  UISwipeActionsConfiguration?  {

    let renameAction  = contextualToggleRenameAction(forRowAtIndexPath: indexPath)
    let lastResAction = contextualToggleLastResponseAction(forRowAtIndexPath: indexPath)

    let swipeConfig = UISwipeActionsConfiguration(actions: [renameAction, lastResAction])
    swipeConfig.performsFirstActionWithFullSwipe = false
    return swipeConfig
}

func contextualToggleLastResponseAction(forRowAtIndexPath indexPath: IndexPath) -> UIContextualAction {
    let sensorData = sensorsList?[indexPath.row]
    var lastResponse = ""
    if sensorData != nil{
        if let lstRes = sensorData!["last_response"] as? String{
            lastResponse = lstRes
        }
    }
    let action = UIContextualAction(style: .normal, title: lastResponse) { (contextAction: UIContextualAction, sourceView: UIView, completionHandler: (Bool) -> Void) in
        print("Last Response Action")
    }
    action.backgroundColor = UIColor(red: 61/255, green: 108/255, blue: 169/255, alpha: 1.0)
    return action
}
like image 845
Shiva Kumar Avatar asked Mar 18 '19 11:03

Shiva Kumar


3 Answers

Holy crap, I fixed this stupid issue.

Yes, yes make sure tableView.allowsSelectionDuringEditing = true and tableView.allowsMultipleSelectionDuringEditing = true.

But...

Shout-out to this SO answer which almost directly led me on the way to success (see here).

KEY: Re-select/de-select the rows in your implementation of setEditing, which is a method you override. UITableView goes into editing mode when swiping.

IMPORTANT NOTE: Call super.setEditing(...) before any of your code, as shown below, or it likely won't work, or at least not perfectly.

override func setEditing(_ editing: Bool, animated: Bool) {
    super.setEditing(editing, animated: animated)
    for i in 0..<your data.count {
        if this item is selected {
            self.tableView.selectRow(at: IndexPath(row: i, section: 0), animated: false, scrollPosition: .none)
        } else {
            self.tableView.deselectRow(at: IndexPath(row: i, section: 0), animated: false)
        }
    }
}
like image 163
Joshua Wolff Avatar answered Sep 17 '22 18:09

Joshua Wolff


A swipe is considered as an edit, so you can enable allowsSelectionDuringEditing if you want to keep the selected state:

tableView.allowsSelectionDuringEditing = true
like image 24
Thomas Avatar answered Sep 20 '22 18:09

Thomas


Depending on indexPathsForSelectedRows doesn't always give the expected result.

Instead you should maintain and array of selectedIndexPaths.

Here is a code snippet to demonstrate:

var selectedIndexPaths = [IndexPath]()
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if selectedIndexPaths.contains(indexPath) {
       selectedIndexPaths.removeAll { (ip) -> Bool in
        return ip == indexPath
    }else{
       selectedIndexPaths.append(indexPath)
    }
}
like image 42
jshivam Avatar answered Sep 21 '22 18:09

jshivam