My storyboard-based UITableViewController
subclass pushes another view controller into the navigation when the user taps one of the table view cells.
I am using a segue to accomplish this, and not doing it programmatically with pushViewController(:animated:)
.
The problem I'm having is that my table view cell stays highlighted (light gray) all along, even after popping the view controller (again, with an 'unwind' segue). The only way to clear it is to call tableView.reloadData()
.
I have tried:
Setting:
self.clearsSelectionOnViewWillAppear = true
in viewDidLoad()
(Should not be necessary, since it's already the default: The template code has self.clearsSelectionOnViewWillAppear = false
commented out, and suggests to uncomment it to override the default functionality).
Also:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if let indexPath = tableView.indexPathForSelectedRow {
tableView.deselectRow(at: indexPath, animated: true)
}
}
...to no avail.
EDIT: Turns out viewDidAppear()
is not called on navigation pop, only after being added to the view hierarchy (e.g., addSubview()
). Placing this code in viewWillAppear()
does the trick. But my question at the end of this post still stands.
I have also tried implementing this method:
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
...but it is not being called (perhaps because of the segue?)
The only thing that successfully unhighlights the cell is calling:
tableView.deselectRow(at: indexPath, animated: true)
...from within prepareForSegue()
. But that happens on push, and I want to de-highlight my cell on pop.
Do I need to setup a dedicated unwind method for the push (cell tap) segue, and unhighlight there?
Why doesn't it work out-of-the-box, even though I am subclassing UITableViewController
?
Like what you mention, using tableView.deselectRow(at: indexPath, animated: true)
However, instead of having it in:
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
You should be putting it in:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// You other cell selected functions here ...
// then add the below at the end of it.
tableView.deselectRow(at: indexPath, animated: true)
}
didDeselectRowAt
will not be called until a row is deselected. So in order to de-select the cell, you should be adding it in the didSelectRow
. This way whenever a cell is selected and didSelectRow
get trigger, you will run your other code and also de-select
the cell at the end of it.