简体   繁体   中英

Precise calculation of the Height of a UITableViewCell Based on Text

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:

在此处输入图片说明

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

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

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM