1

I have a UILabel inside a UITableViewCell. I am not using autolayout, but creating and adding the views manually. The UILabel can contain a variable amount of text so in my tableview delegate i implement heightForRowAtIndexPath.

- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
   TableCellWithDocument *cell = (TableCellWithDocument*)[self tableView: tableView cellForRowAtIndexPath: indexPath];
   NSLog(@"Cell frame: %@", NSStringFromCGRect(cell.frame));
   return [cell heightForCellForWidth: cell.frame.size.width];

The problem i'm having is that when this delegate method is called, the frame size of the cell is not correct. It just returns "default" 320x44. So when i try to calculate the label size, i have the wrong cell width and my cell height gets the wrong height.

In my subclassed TableCellWithDocument class, i can override layoutSubviews and get the correct cell width, but that is too late since heightForRowAtIndexPath has already been called.

How should i handle this?

Trj
  • 657
  • 9
  • 21

2 Answers2

0

You are doing it in recursive manner. If you carefully debug your code, you will find that heightForRowAtIndexPath is called first to estimate cell height, and cellForRowAtIndexPath is called later.

Ideally, within heightForRowAtIndexPath, you should take all your data source content, and estimate the size of it. cellForRowAtIndexPath should be able to use this height to set the cell content.

For example, if there is some text to be displayed, you could use [UILabel sizeThatFits] or [NSString sizeWithFont] method to estimate cell.textLabel size, and so on.

Remember that no answer is the right answer and you must do tweaks according your own data - be it strings, images or anything else. It's data size, not the size of your controls - that must decide what you return from heightForRowAtIndexPath.

Nirav Bhatt
  • 6,940
  • 5
  • 45
  • 89
0

Try doing this in Your heightForRowAtIndexPath

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGSize size = [text sizeWithFont:[UIFont fontWithName: @"YourFont" size:24.0];
                   constrainedToSize:CGSizeMake(kMessageTextWidth, CGFLOAT_MAX)
                       lineBreakMode:NSLineBreakByWordWrapping];


    return MAX(size.height + 17.0f);
}
Geet
  • 2,427
  • 2
  • 21
  • 39
  • sizeWithFont method is deprecated for iOS7.0 onward. You will need to use boundingRectWithSize:options:attributes:context: method instead. – Jim Tierney Jul 28 '14 at 21:16