0

I've gotten different perspectives on this from different sources, and I'd like to clear it up. When calling tableView:heightForRowAtIndexPath:, a required method, can I dynamically resize cell heights depending on the data within them? Can this be done 'on the fly' or do I need to standardize five or six prototype cells and choose which cell to use based on its reuseIdentifier.

If for example I called

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
  return [tableView indexPathForSelectedRow]*20;
}

would this draw all necessary cells immediately, and then still be swapping out these same cells or would it redraw the cells once they leave the screen. Why would I need to have multiple prototype cells?

Jared
  • 3,651
  • 11
  • 39
  • 64

2 Answers2

1

Answer: yes - yes, it can be done "one the fly" as you put it. Yes you can give every cell a different height using that method, even if the cells have the same reuse identifier. I typically use different reuse identifiers for cells if I'm going to display different things, with different cells.

BTW, heightForRowAtIndexPath is not a required method - it's only necessary if you have cells of different heights (as you want to do).

BTW2: heightForRowAtIndexPath will be called for every index path before the cell is rendered, so the table view can compute the total height of the content.

BTW3: your implementation of heightForRow... is weird: First of all, indexPathForSelectedRow returns an indexPath, which is not a scalar (and thus you can't * 20 it) - this shouldn't compile, actually. Second of all, that would give every cell the same height, if it even worked.

Colin
  • 3,670
  • 1
  • 25
  • 36
1

In iOS 8 you can use auto layout to adopt to different heights. This is covered in this answer very nicely.

Under iOS 7 and earlier this is not possible with auto layout. UIKit uses a two step process to render a table view:

  1. Gather the height of all cells in the table view
  2. Get UITableViewCell objects when they need to be displayed

The height must be returned by - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath.

This delegate method is called every time for each cell as Apple states in the documentation:

Every time a table view is displayed, it calls tableView:heightForRowAtIndexPath: on the delegate for each of its rows, which can result in a significant performance problem with table views having a large number of rows (approximately 1000 or more).

To speed things up - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath was introduced by iOS 7 to give an approximation of the height.

Can I dynamically resize cell heights depending on the data within them?

Yes, you can, but you have to do it within heightForRowAtIndexPath. You cannot change the height dynamically from within - (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath;

Community
  • 1
  • 1
Klaas
  • 22,394
  • 11
  • 96
  • 107