Is it safe to call rectForRowAtIndexPath when using Self-Sizing cells?

I'm seeing some interesting behavior in an app that uses a UITableView with self-sizing cells.


The cells are all really tall. What I'll do sometimes is query for the rectForRowAtIndexPath for some row like 6, and get one value (let's call it A). Then if I scroll that cell into view and inspect it's frame, it's different than A. Then usuaully if I continue to scroll down, and then later scroll back up to row 6, if I query rectForRowAtIndexPath the value will be something different than B. If I scroll down and back again, it will remain B.


It seems like rectForRowAtIndexPath won't report a reliable value until actually scrolling the cell into view, which makes sense. Is there a workaround to get the correct value without using explicitly sized cells?

Accepted Reply

There are two factors to consider.


1. There is no guarantee that the cell view exists for a row that is not visible. Cell views that scroll off the screen are re-used (re-sized and re-configured) for other rows that scroll onto the screen. (There is some caching involved, so it's difficult to predict whether an individual cell will hang around or not.)


2. It's too expensive to calculate the height of every row at one time. In other words, it's too expensive to run auto-layout on every off-screen cell. Instead, the table view is going to use some kind of estimate for some cells, and adjust the height (and related stuff like scroll bar extents etc) when the cell is scrolled onto the screen.


You need to take these things into account when designing your app. For example, if you are displaying a paginated document using a table view, you won't be able to paginate correctly based on the estimated heights. Depending on your app, this can be a difficult problem to solve.

Replies

There are two factors to consider.


1. There is no guarantee that the cell view exists for a row that is not visible. Cell views that scroll off the screen are re-used (re-sized and re-configured) for other rows that scroll onto the screen. (There is some caching involved, so it's difficult to predict whether an individual cell will hang around or not.)


2. It's too expensive to calculate the height of every row at one time. In other words, it's too expensive to run auto-layout on every off-screen cell. Instead, the table view is going to use some kind of estimate for some cells, and adjust the height (and related stuff like scroll bar extents etc) when the cell is scrolled onto the screen.


You need to take these things into account when designing your app. For example, if you are displaying a paginated document using a table view, you won't be able to paginate correctly based on the estimated heights. Depending on your app, this can be a difficult problem to solve.