UILabel sizeThatFits not working

我们两清 提交于 2019-12-10 15:16:59

问题


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?


回答1:


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

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



回答2:


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);
}



回答3:


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...




回答4:


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];



回答5:


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.


来源:https://stackoverflow.com/questions/19628568/uilabel-sizethatfits-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!