UITableViewCell accidentally tapped while scrolling

Viewed 199

I have a UITableView. Each row is tappable and triggers an action (tapping updates the cell content, on the main thread, then adds something in CoreData in a background thread).

I'm using

func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath)

in UITableViewDelegate to detect taps, because in my experience tapping on the rows with this method was more reactive rather than using didSelectRowAt, and I want users to be able to rapidly tap several times in sequence on the same row, like a tally.

But now I experience an issue where sometimes just scrolling the tableview can accidentally trigger a tap action.

As if the first time the finger touches the screen when beginning the scroll gesture, the cell was registering a tap instead of "start scroll". The UITableViewCell is now a bit too sensitive.

I thought maybe I could stop using didHighlightRowAt and instead add a gesture recognizer on each UITableViewCell, and only trigger the actions if the recognizer sees no scrolling, but it doesn't feel right.

What would be the way to reach some sort of middle ground?

I mean, keep the cells reactive, but avoid triggering a tap when the user is just starting scrolling. Maybe I'm making a mistake by using didHighlightRowAt in this situation?


Edit: it even happens right after the app launches. I was just able to reproduce it for the first time: it happens if the finger rests on the cell for a short time before starting the scroll gesture. Which makes sense, I guess: touch the row and it's highlighted, even if the finger is not lifted from the screen. I didn't notice because I always do a fast swipe-up to scroll, my finger never rests on the screen.

1 Answers

I guess your problem is that when scrolling the cells are being reused and as their status remains highlighted, the didHighlightRowAt delegate methods is being called. A possible solution is to reset the highlighted value in prepareForReuse in your custom cell subclass:

override func prepareForReuse() {
    super.prepareForReuse()
    isHighlighted = false
}

Or you can also check if a cell should be highlighted using the shouldHighlightRowAt delegate method.

Related