For Clarity I have a UIView Controller
with a top view containing a textfield
. I also have a tableview
below that each row containing
I would avoid reloading the table view at all so that you don't disturb the first responder status of your text. You could either (1) insert and delete only what's changed or (2) redecorate cells that need updating.
So, instead of calling myTableView.reloadData()
, figure out which index paths need to be added or removed and call the appropriate methods.
myTableView.insertRows(at: newIndexPaths, with: .automatic)
myTableView.deleteRows(at: oldIndexPaths, with: .automatic)
This requires a more modular approach to how you are dequeuing cells. Instead of doing this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
cell.data = dataArray[indexPath.row]
return cell
}
Do this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
decorate(cell, at: indexPath)
return cell
}
func decorate(_ cell: UITableViewCell, at indexPath: IndexPath) {
cell.data = dataArray[indexPath.row]
}
That way later on you can redecorate, i.e. update the content and configuration of the cells without reloading and disturbing the first responder status:
for cell in myTableView.visibleCells {
if let indexPath = myTableView.indexPath(for: cell) {
decorate(cell: cell, at: indexPath)
}
}
Have you tried storing the indexpath before reloading your tableview and using it to find your cell and set the textfield inside it as first responder after the reload ?