I have been struggling with this for months in my project.
Here's the deal: I have a UITableView with just 1 section, but the heights of the UITableViewCells differ. Each UITableViewCell represents an object, and new objects are constantly becoming available, and inserted into the UITableView. The only way to effectively discover the height of a new object which will be displayed in the table is to draw it once (run the code that draws the UITableViewCell and look at what the resulting height is).
Ah, but there's the problem! The UITableView delegate method tableView:heightForRowAtIndexPath: is called BEFORE the cell is drawn for the first time! This makes sense: the table wants to position the cells before drawing them.
I've been experimenting LOTS and can find only 2 options, both of which have major downsides:
My solution thus far has been to use #2, but to try to alleviate the problem by making it so that the height-tests only happen every 1/4 of a second, which helps to "space out" the testing, so that the main thread is not locked too much. But, the solution is inelegant and still causes lag problems, especially on older devices. The lag is bad enough that I really need a better solution.
For calculating the height, this and this answer suggest you could draw off-screen in a background thread using CGLayer. Link to iOS documentation to CGLayer.
And to cache the height depending on some data id that is being displayed in a cell you could use code like this:
-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
NSString* objectId = [self getObjectIdForPath:indexPath];
if (![self->idToCellHeight objectForKey: objectId])
{
CGFloat height = [object calculateHeightForId:objectId];
[self->idToCellHeight setObject:[NSNumber numberWithFloat:height] forKey: objectId];
}
return [[self->idToCellHeight objectForKey:objectId] floatValue];
}
Of course the first draw will still have to be done without knowing the exact height, but if you can't calculate the height based on the data displayed then there is no workaround.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With