0

I have an issue with changing height of cell depending on text length. I'm trying to calculate cell height using this code:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [self dynamicHeightAtIndexPath:indexPath] + 32;
}

- (CGFloat)dynamicHeightAtIndexPath:(NSIndexPath *)indexPath
{
    CGSize maximumSize = CGSizeMake(275, 9999);
    UIFont *myFont = [UIFont fontWithName:@"Avenir-Light" size:15.0];
    CGSize stringsize = [[[self.userAdsArray objectAtIndex:indexPath.row] valueForKey:@"name"]
                         sizeWithFont:myFont
                         constrainedToSize:maximumSize
                         lineBreakMode:NSLineBreakByWordWrapping];
    return stringsize.height;
}

And I've got these results (5th cell from the top is broken):

enter image description here

Lebyrt
  • 1,376
  • 1
  • 9
  • 18
  • http://stackoverflow.com/questions/23077829/calculate-tableview-list-cell-height-to-fit-string/23080315#23080315 – Nick Apr 22 '14 at 17:54

3 Answers3

0

Try this instead:

- (CGFloat)dynamicHeightAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *myText = [[self.userAdsArray objectAtIndex:indexPath.row] valueForKey:@"name"];
    CGRect textSize = [myText boundingRectWithSize:CGSizeMake(275.0f, CGFLOAT_MAX)
                       options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
                       attributes:@{NSFontAttributeName: [UIFont fontWithName:@"Avenir-Light" size:15.0f]}
                       context:nil];
    return fabs(textSize.size.height);
}

Not sure what type does the object for key @"name" have, but the above code works for NSString. Hence the declaration is for clarity.

Lebyrt
  • 1,376
  • 1
  • 9
  • 18
MDB983
  • 2,444
  • 17
  • 20
  • Nope, this doesn't fix it. The same issue is occurring. Thanks though! – lizbarrett Apr 24 '14 at 16:43
  • Then check where you set the font for the Cell Label, i suspect you're setting it to something other than [UIFont fontWithName:@"Avenir-Light" size:15.0]; or the width possibly isn't 275.0 – MDB983 Apr 24 '14 at 18:48
  • The only other place the font is set is on the dynamic prototype cell on the storyboard. – lizbarrett Apr 26 '14 at 17:56
0

I just wrap the text height calculate function to a category of NSString.

In the .h file:

@interface NSString (Additions)

- (CGSize)sizeWithFont:(UIFont *)font;
- (CGSize)sizeWithFontSize:(float)fSize constrainedToSize:(CGSize)cSize;
- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)cSize;

@end

In the .m file:

#import "NSString+Additions.h"

#define kSystemVersion ([[UIDevice currentDevice] systemVersion].intValue)

@implementation NSString (Additions)

- (CGSize)sizeWithFont:(UIFont *)font
{
    return [self sizeWithFont:font constrainedToSize:(CGSize)
            {MAXFLOAT, MAXFLOAT}];
}

- (CGSize)sizeWithFontSize:(float)fSize constrainedToSize:(CGSize)cSize
{
    UIFont *font = [UIFont systemFontOfSize:fSize];
    return [self sizeWithFont:font constrainedToSize:cSize];
}

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)cSize
{
    if (kSystemVersion < 7)
    {
        CGSize size = [self sizeWithFont:font constrainedToSize:cSize
                       lineBreakMode:NSLineBreakByWordWrapping];
        return size;
    }
    else
    {
        NSDictionary *stringAttributes = @{NSFontAttributeName:font};
        CGRect rect = [self boundingRectWithSize:cSize
                       options:NSStringDrawingUsesLineFragmentOrigin |
                               NSStringDrawingUsesFontLeading
                       attributes:stringAttributes
                       context:nil];

        return rect.size;
    }
}

@end

Then, just calculate the string's height in the place you want. such as:

CGSize cSize = (CGSize){THE_LABEL_WIDTH_HERE, MAXFLOAT};
NSString *tmpString = @"Hello there. I'm junkor, and you can call me jun.";

// will use the system font
float height = [tmpString sizeWithFontSize:15 constrainedToSize:cSize].height;

The height is what you want. Sometimes, when you calculate the size of the text, you can cache the size to the data entity, such as in the tableView's delegate function:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

When you reload data or scroll the tableView, it always calculates, makes a cache to the height (or size). Make sure you just calculate once for every text, it's better.

Lebyrt
  • 1,376
  • 1
  • 9
  • 18
junkor
  • 373
  • 1
  • 11
-1

Please, try this:

- (CGFloat)dynamicHeightAtIndexPath:(NSIndexPath *)indexPath
{
    CGSize maximumSize = CGSizeMake(275, 9999);
    UIFont *myFont = [UIFont fontWithName:@"Avenir-Light" size:15.0];

    NSString *text = [[self.userAdsArray objectAtIndex:indexPath.row] valueForKey:@"name"];
    CGFloat height = [text sizeWithFont:myFont constrainedToSize:maximumSize].height;

    return height;
}
Lebyrt
  • 1,376
  • 1
  • 9
  • 18