Skip to content

Instantly share code, notes, and snippets.

@hannesoid
Last active June 22, 2023 14:26
Show Gist options
  • Save hannesoid/b119b0d12dcbd12d29335d4566bea41d to your computer and use it in GitHub Desktop.
Save hannesoid/b119b0d12dcbd12d29335d4566bea41d to your computer and use it in GitHub Desktop.
iOS15 UITableView Duplicate Cell Usage Issue

This only happens on iOS 15 and only when building with Xcode 13. UITableView with (non-diffable) UITableViewDataSource and just one cell type.

Steps

The set up where the issues arises is, we have a row in which we are editing text, insert another after it, and want to continue editing in the new row.

  • [row 0] cell_0 with textView that is firstresponder

Then we call insertRows(at: [.init(row: 1, section:0)], with: …). Within UITableViewDataSource.tableView(…, cellForRowAt:) we correctly get tableView do dequeue a new instance cell_1. (side note: all cells have same reuseIdentifier). In the same tableView(…, cellForRowAt:) method we configure the cell's textView to become the new firstResponder.

Expected

  • [row 0] cell_0
  • [row 1] cell_1 with textView that is firstresponder

Actual

  • [row 0] cell_1 (same cell class instance as the new row)
  • [row 1] cell_1

We suddenly have the situation, that when asking the tableView for it's .cellForRow(at: IndexPath), the cells are no longer unique for each row. This is now a broken situation, where cells are no longer correctly updated because tableView.cellForRow(at:) returns the same instance for different rows. The issue can be resolved by scrolling away and back. tableView.visibleCells interestingly doesn't show two same cells, only cellForRow(at: IndexPath) does. Turning of prefetching didn't change the issue.

Fix

The issue does not arise

  • when not making the inserted cell's textView firstResponder during UITableViewDataSource.tableView(…, cellForRowAt:), also not when making it firstResponder after calling insertRows(at: […])

Sample Project

I tried but couldn't yet reproduce in a tiny sample project, so there must be additional circumstances in our project. Maybe I will try a bit more. In the MindNode workspace, the Outline Sandbox with just one entry is enough.

Theories

I assume that it has something to do with tableView holding on to the cell with the firstResponder, maybe it has a moment where it thinks that both rows the first responder and confuses the two.

@yangyangwoo
Copy link

Dealing with this issue too..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment