Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom heightForRowAtIndexPath (CGSize sizeWithFont) with NSAttributedString iOS

I have a table view where my cells height is defined dynamically depending on the text it is representing.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //getting my text for this cell, the row etc ...
    ...
    //here is the part interesting us
    NSAttributedString* theText = [myTextForThisCell objectAtIndex:indexPath.row];

    NSInteger labelWidth = self.tableView.bounds.size.width-HORIZONTAL_CELL_PADDING;

    CGSize textSize = [theText sizeWithFont:[UIFont systemFontOfSize:customFontSize] constrainedToSize:CGSizeMake(labelWidth, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping];

    return textSize.height+VERTICAL_CELL_PADDING;
}

Ok so now my problem. The tableview is the result of a search action which after scanning a plist file shows the lines containing a given string.

Up to now that was it. But now with iOS 6 and NSAttributedString allowing easily to bold part of strings I decided to bold the search word.

It is working, it bolds the words I want but now I am no more able to calculate the cell height as sizeWithFont ask for a NSString. And as bolding takes a wider width I cannot simply calculate the cell height with the string without attributes.

I am simply stuck here.

Anyone can help me ?

like image 240
HpTerm Avatar asked Nov 29 '22 16:11

HpTerm


1 Answers

In fact I simply had to read apple documentation of NSAttributedText.

In my case I have to replace the last two lines of code by

CGRect rectSize = [theText boundingRectWithSize:CGSizeMake(labelWidth, MAXFLOAT) 
                         options:NSStringDrawingUsesLineFragmentOrigin context:NULL];

return rectSize.size.height+VERTICAL_CELL_PADDING;

FOLLOW UP iOS 7

I have been struggling making this work in iOS7 with attributed text.

Apple documentation says

In iOS 7 and later, this method returns fractional sizes (in the size component of the returned CGRect); to use a returned size to size views, you must use raise its value to the nearest higher integer using the ceil function.

Which way obviously not working for me ! For me the solution was to add +1 to the ceil of height. This is probably a bug from Apple, but for me now everything works as in iOS6.

CGRect rectSize = [theAttributedText boundingRectWithSize:CGSizeMake(labelWidth, MAXFLOAT) 
                          options:NSStringDrawingUsesLineFragmentOrigin context:NULL];

return ceil(rectSize.size.height) + 1 + VERTICAL_CELL_PADDING;
like image 161
HpTerm Avatar answered Jun 15 '23 07:06

HpTerm