Mike Gabriel
Mike Gabriel

Reputation: 498

UILabel with -[sizeWithFont:constrainedToSize:lineBreakMode] is cutting off words

UILabel inside of a UITableViewCell. On cell tap, height expands and a second UILabel appears with various amounts of data.

The problem is, if the line wraps, sizeWithFont:constrainedToSize:lineBreakMode: does not return the proper height and cuts off the bottom line.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    labelExpanded = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
    labelExpanded.font = [UIFont boldSystemFontOfSize:11];
    labelExpanded.textAlignment = UITextAlignmentLeft;
    labelExpanded.lineBreakMode = UILineBreakModeWordWrap;
    labelExpanded.numberOfLines = 0;
    [cell.contentView addSubview:labelExpanded];

    CGSize constraint = CGSizeMake(300, 20000);
    CGSize size = [expandedDetails sizeWithFont:[UIFont boldSystemFontOfSize:11] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

    [labelExpanded setText:expandedDetails];
    [labelExpanded setFrame:CGRectMake(16, 30, 248, size.height)];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(// Row is Expanded)
    {
        CGSize constraint = CGSizeMake(300, 20000);
        CGSize size = [sameTextAsLabel sizeWithFont:[UIFont boldSystemFontOfSize:11] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

        // I found +8 to height added nice padding
        CGFloat height = size.height + 8;
    }
    else // Row is not expanded
        return 30;
}

The same text is fed to both, it consists of a string with multiple new lines \n. If the line is longer than width, word wrap does its job but when calculating its dynamic height, it fails to include the wrapped line.

If I add any value to the [labelExpanded setFrame:height] such as [size.height + 30] my wrapped line shows up. However, if the line isn't wrapped, it adds unnecessary whitespace.

I haven't been able to find a solution online for this.

Upvotes: 2

Views: 5068

Answers (2)

unexpectedvalue
unexpectedvalue

Reputation: 6139

    CGSize constraint = CGSizeMake(300, 20000);
    CGSize size = [expandedDetails sizeWithFont:[UIFont boldSystemFontOfSize:11] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

    [labelExpanded setText:expandedDetails];
    [labelExpanded setFrame:CGRectMake(16, 30, 248, size.height)];

Why is the label frame width 248 and constraint width is 300?

Upvotes: 3

Anomie
Anomie

Reputation: 94794

One thing I note is that you are calculating the size based on a width of 300, but sizing the label at 248.

Upvotes: 7

Related Questions