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)
}
}