Sean Danzeiser
Sean Danzeiser

Reputation: 9243

UILabel sizeThatFits not working

I'm trying to calculate the height for a UITableViewCell so I've defined a class method that looks like this

+ (CGFloat)heightWithText:(NSString *)text
{
    SizingLabel.text = text;
    [SizingLabel sizeThatFits:CGSizeMake(LABEL_WIDTH, CGFLOAT_MAX)];

    return (TOP_MARGIN + SizingLabel.frame.size.height + BOTTOM_MARGIN);
}

I've defined SizingLabel like this:

+ (void)initialize
{
    SizingLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    SizingLabel.numberOfLines = 0;
    SizingLabel.lineBreakMode = NSLineBreakByWordWrapping;
}

However, if i stick a breakpoint in the -heightWithText: method, i notice that the dimensions of SizingLabel never change and i thus get an incorrect value. Why is that?

Upvotes: 5

Views: 22466

Answers (5)

E. Rivera
E. Rivera

Reputation: 10938

As said above, sizeThatFits: (and thus sizeToFit) do not work well with UILabel objects.

You better use the preferred textRectForBounds:limitedToNumberOfLines: method:

+ (CGFloat)heightWithText:(NSString *)text
{
    resizingLabel.text = text;
    CGSize labelSize = [resizingLabel textRectForBounds:CGRectMake(0.0, 0.0, LABEL_WIDTH, CGFLOAT_MAX)
                                 limitedToNumberOfLines:0].size; // No limit

    return (TOP_MARGIN + labelSize.height + BOTTOM_MARGIN);
}

Upvotes: 7

TamilKing
TamilKing

Reputation: 1643

Do this in your Custom Cell Class:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code

        //Message Label
        lbl_name = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 300, 25)];            

        [lbl_name setFont:[UIFont fontWithName:@"Helvetica" size:16.0f]];
        lbl_name.lineBreakMode = UILineBreakModeWordWrap;
        lbl_name.numberOfLines = 0;
        [lbl_name sizeToFit];
        [self.contentView addSubview:lbl_name];

        //Time 
    }
    return self;
}    

-(void)resizeNameLabel:(NSString *)text
{
    CGSize constraint = CGSizeMake(300 , 20000.0f);
    CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:16.0f] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
    [lbl_name setFrame:CGRectMake(10, 5, 300, MAX(size.height, 25.0f))];//300 Label Width
    [lbl_name setText:text];
}

Do this in main class..

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

    if (cell == nil) 
    {
        cell = (CustomCell *)[[CustomCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cell"];
    }
        [((CustomCell *)cell) resizeNameLabel:text];

    return cell;
}

Just do like this...

Upvotes: 3

johnboiles
johnboiles

Reputation: 3524

For simple sizing of UILabels that have attributed text, I added this category to UILabel.

@implementation UILabel (PAUtils)

- (CGSize)jb_attributedSizeThatFits:(CGSize)size
{
    CGRect textRect = [self.attributedText boundingRectWithSize:size options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) context:nil];
    return textRect.size;
}

@end

Two things to note:

  1. When not setting attributedText (but instead just using text) this method doesn't take into account the numberOfLines property.
  2. boundingRectWithSize returns fractions of points. If you are using the values returned from this method for layouts, you should probably ceilf the width and height.

Upvotes: 0

Jing
Jing

Reputation: 536

below code is to calculate the rect for dynamic text length (ios7 version)

- (CGRect)labelFrameWithText:(NSString *)text
{
    CGRect rect;

    // the font of your text
    UIFont *font = [UIFont systemFontOfSize:15.0]; 
    NSDictionary *attributes = @{NSFontAttributeName: font};

    // the first parametric CGSize is the max size that the rect's size can be
    CGRect boundingRect = [text boundingRectWithSize:CGSizeMake(youImageWidth, 100.0)
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:attributes
                                              context:nil];

    //the rect of the UILabel
    //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.
    rect = CGRectMake(yourLabelOriginX,
                      yourLabelOriginY,
                      ceil(boundingRect.size.width),
                      ceil(boundingRect.size.height));

    return rect;
}

and after you get the rect, use it to calculate your cell size

----------------older version-------------------

CGSize contentSize = [content sizeWithFont:font
                             constrainedToSize:CGSizeMake(maxWidth, maxHeight)
                                 lineBreakMode: NSLineBreakByWordWrapping];

Upvotes: 0

OnkarK
OnkarK

Reputation: 3793

+ (CGFloat)heightWithText:(NSString *)text
{
    SizingLabel.text = text;
    CGSize labelSize = [SizingLabel sizeThatFits:CGSizeMake(LABEL_WIDTH, CGFLOAT_MAX)];

    return (TOP_MARGIN + labelSize.height + BOTTOM_MARGIN);
}

Upvotes: 5

Related Questions