My app uses a UITableView
with a UINavigationController
to show a more detailed view when a row of the table is tapped - the basic drill-down routine.
When I tap on a row, it is highlighted, but the delegate methods tableView:willSelectRowAtIndexPath:
or tableView:didSelectRowAtIndexPath:
are not called (verified using debugger).
Now here's the weird part:
There are some other table views in the app (they don't drill down) and none of them exhibit the issue.
If I tap the row rapidly and repeatedly, after many tries (10 - 20 is normal), tableView:willSelectRowAtIndexPath:
and tableView:didSelectRowAtIndexPath:
are called and processing continues normally.
The problem occurs only on an (any, actually) iPad running iOS 6. It works fine with iPads running iOS 5, or with any iPhone running any iOS version, 6. It also works with the iPad simulator using iOS 5 or 6.
So it seems that something is receiving the tap before the delegate methods are called. But what?
I not using any UITapGestureRecognizer
, so that is not the issue.
I am not using multiple UITableViewControllers
for the table, so this is also not the issue.
The resolution is really weird: the UITableViewController registered for all notifications. In the handler for the notifications, the table view data was being reloaded using
[self.tableView reloadData]
According to Apple DTS, when the table reloads data, this causes a notification to be sent to the observer, causing a race condition ...
No explanation for why it would work sometimes or why it would always work on an iPhone. But registering only for a small subset of notifications (i.e. the ones I was really interested in) fixed the problem!