I've got an iPad app with a UITableView that has roughly 100 rows. The cells are custom, I've implemented heightForRowAtIndexPath to tell the UITableView how big my cells are.
I'm using this:
[tableView scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
to scroll the table to a given row. This works perfectly for row 1-75. Row 76 is slightly off the middle, 76-79 are slightly more off, and as of row 80, it no longer scrolls to the correct position at all. It just stays put with row 79 being the last visible row. I can still manually scroll the table by dragging my finger when this happens; it's observably not yet at the end. It seems however that programmatically, scrollToRowAtIndexPath thinks it has reached the end of the table before it actually has. I would expect this behaviour at the end of the table, not at 3/4 of the rows.
I am struggling to debug what is happening here; I would appreciate any pointers that help me find out why the table is thinking it is already at the end when I call scrollToRowAtIndexPath.
I had the same problem and I think I understand what happens: the table view is already performing another animation and the scrollToRowAtIndexPath is ignored. Wrapping the method in CATransaction block works for me (swift code):
CATransaction.begin()
tableView.beginUpdates()
tableView.scrollToRowAtIndexPath(cell.indexPath, atScrollPosition: .Middle, animated: true)
tableView.endUpdates()
CATransaction.commit()
Another solution that worked for me was using performSelectorWithDelay, with the delay being long enough for other animations on the table view to finish.
I noticed this question is viewed quite a lot so maybe more people run into this issue. Eventually I found out that it wasn't the tableview's problem. It was positioned in a view that was misbehaving when rotating the device or resizing it from code. The tableview actually extended beyond the boundary of the view it was in, so the output looked weird but if you consider that the tableview ended beyond the boundary of the screen, it actually made sense.
I solved it by cleaning up the view hierarchy and making sure that resizing and rotating worked properly.
try:
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:indexRow inSection:indexSection]
atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
You write you have overridden heightForRowAtIndexPath:, but there is nothing to override. You should have a delegate that implements the UITableViewDelegate protocol, to be called by the tableView.
If that is already the case, you should check that your delegate is correctly working by logging the values in heightForRowAtIndexPath is called, or break in there.