Current set up:
TableView with automatically calculated heights:
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
s
It happens because of the following sequence:
-tableView:heightForRowAtIndexPath:
.contentOffset.y
is now 220.contentOffset.y
which is 220.UITableView now beginning to fill its contents. First it needs to know size of its contents to correctly size and position its scroll indicators. It also needs to know which objects - table header, section headers, rows, section footers and table footer - it should display according to its current bounds
, which position is also represented by contentOffset
. To begin placing that visible objects it first needs to skip objects that falls in invisible vertical range of [0…220].
estimated…
properties and haven't implemented any of tableViewController:estimated…
methods then UITableView asks its delegate about exact height of headers, footers and rows by calling appropriate delegate methods such as -tableView:heightForRowAtIndexPath:
. And if your delegate reports the same number of objects and the same heights for them as before reload, then you will not see any visual changes to position and size of any table elements. Downside of this "strait" behavior became obvious when your table should display large number of rows, lets say 50000. UITableView asks its delegate about height of each of this 50000 rows, and you have to calculate it yourself by measuring your text for each corresponding object, or when using UITableViewAutomaticDimension
UITableView doing the same measuring itself, asking its delegate for cells filled with text. Believe me, it's slow. Each reload will cause a few seconds of interface freeze.estimatedRowHeight
or -tableView:estimatedHeightForRowAtIndexPath:
for rows and by corresponding methods for section headers and footers. By setting estimatedRowHeight
to 60, you telling UITableView to skip three rows (60 * 3 = 180) and to place row 4 with offset of -40 from top visible edge. Hence visual "jump" by 40 pixels up.A "right" solution here would be not to call reloadData
. Reload rows only for changed objects instead, use -reloadRowsAtIndexPaths:withRowAnimation:
. In case of NSFetchedResultsController + UITableView use this classic scheme.