1

I am working on an ios application, and using autolayout I am trying to create a Table View with different row heights.

The layout of the prototype cell is as follows:

enter image description here

I have the main cell (in black) inside it I have a UIView (in red) and inside that view a UILabel (in blue)

The Autolayout constraints I added are as shown on the figure:

The UIView has the following Constraints:

  • 80 to the left edge of the cell

  • 20 from the right edge of the cell

  • 15 from the top edge of the cell

  • 15 from the bottom edge of the cell

The UILabel has the following Constraints:

  • 20 to the left edge of the UIView

  • 15 from the right edge of the UIView

  • 10 from the top edge of the UIView

  • 10 from the bottom edge of the UIView


I need the UILabel to be dynamic in height based on the text size inside of it. To do that, I have done the following:

  1. Set the number of lines of the UILabel to 0
  2. Set the font to Helvetica Neueu with size 15 (in the interface builder)
  3. Set the Lines Break to "Word wrap" (in the interface builder)

in the view Controller, I have implemented the following:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //get the item
    ListItem *item = (ListItem*) self.items[indexPath.row];

    //calculate the label size based on the item title that we will display
    CGSize textSize = [item.title sizeWithFont:[UIFont fontWithName:@"HelveticaNeue" size:15.0] constrainedToSize:CGSizeMake(tableView.frame.size.width - 135.f, 9999.f) lineBreakMode:NSLineBreakByWordWrapping];

    //return the height + the 50 to accomodate with the layout
    return textSize.height + 50.f;
}

Basically what I'm doing is getting the text I need to display (item.title) and I call sizeWithFont to calculate how much I need space for that label and return it.

in the sizeWithFont method I pass the font I am using for the title [UIFont fontWithName:@"HelveticaNeue" size:15.0] and then I constraint the size of the calculation based on the pictures constraints, by getting the width of the tableView and subtracting the margins to get to the label

For the width: I substract 80 (for the UIView left) and 20 (for the label left) and 15 (for the label right) and 20 for the UIView Right)

For the Height I put 9999 as I don't need a constraint on it for the calculations.

After I get the size of the label needed I returned the exact height plus the 15, 10 ,10 and 15 for the vertical margins of the label (total = 50) return textSize.height + 50.f;


The problem:

Although I am doing exact calculation, but when running the app it is not 100% precise. While most cases I get a precise height, but in some cases (especially when we have for example 3 lines in the label, and the 3rd line has one one word), the cell get a height corresponding to 2 lines only and cutting the third one. increasing the height by trial and error might be possible but it will also affect the height of the cells that were displayed well.

So my question is, what am I doing wrong with my calculations? and is there a way to have a dynamic height for the cells based on the text in the label, when using autolayout?

Thanks

Y2theZ
  • 10,162
  • 38
  • 131
  • 200
  • Why do you use `tableView.frame.size.width - 135.f`? Aren't you able to access the `frame` of the `UILabel` directly? – lootsch Mar 08 '14 at 22:10
  • @lootsch no. That's the biggest issue in ios. It needs to calculates the height of the table view before drawing the content (That was a design decision and I don't know why) but by the time the table height is calculated through the heightForRowAtIndexPath the views are not drawn yet and they all have a size of zero. The table view width is the only thing accessible at that time – Y2theZ Mar 08 '14 at 22:26
  • sorry, my bad. i remember this topic. I had to handle this issue many times by myself, and still forget this problem :/ But I can't see a miscalculation. – lootsch Mar 08 '14 at 22:45
  • Any chance the fonts don't match? You'd be calculating based on Helvetica Neue Regular, I think. What's the font of the `UILabel`? Being off by one word makes me think font metrics. I don't see another error. – mbm29414 Mar 09 '14 at 04:58
  • @mbm29414 thank you that was the issue. I was using a Helvetica Neue Bold in the interface builder but specifying the regular in the code. Add this as an answer to accept it. – Y2theZ Mar 09 '14 at 13:49

2 Answers2

1

Any chance the fonts don't match?

You'd be calculating based on Helvetica Neue Regular, I think.

What's the font of the UILabel? Being off by one word makes me think font metrics.

I don't see another error

mbm29414
  • 11,558
  • 6
  • 56
  • 87
0

If you want precise, use the prototype cell approach. It is inherently precise because you're getting the height of an actual cell.

Using this approach for dynamic label height generally involves setting the label's text, calling sizeToFit and then getting the label's intrinsicContentSize. Here is an example implementation.

Community
  • 1
  • 1
Timothy Moose
  • 9,895
  • 3
  • 33
  • 44
  • OP specified he's using a prototype. – mbm29414 Mar 09 '14 at 04:57
  • @mbm29414 You misunderstand. The link discusses an approach where you instantiate a prototype cell and use it to calculate the cell height. Not what the OP is doing. – Timothy Moose Mar 09 '14 at 04:59
  • SO should be the final stop for the answer, not a link that can change/break. You used specific terminology to which I replied. Based on its inclusion in Xcode, Apple already has a claim on that terminology. I'd either explain your answer or update the terms in your link to make it clear that you're NOT talking about Apple-style prototype cells. – mbm29414 Mar 09 '14 at 05:05