【问题标题】:UILabel sizeThatFits not workingUILabel sizeThatFits 不起作用
【发布时间】:2013-11-06 20:35:05
【问题描述】:

我正在尝试计算 UITableViewCell 的高度,因此我定义了一个如下所示的类方法

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

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

我已经这样定义了 SizingLabel:

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

但是,如果我在 -heightWithText: 方法中设置断点,我注意到 SizingLabel 的尺寸永远不会改变,因此我得到的值不正确。这是为什么呢?

【问题讨论】:

  • -(CGSize)sizeThatFits:返回文本适合标签的大小。
  • 啊,好吧,它实际上也没有调整标签的大小吗?
  • 是的,它只是返回一个尺寸。
  • @SeanDanzeiser: 允许您标记多行吗?
  • 经过测试,当您的属性仅适用于您的文本范围时,boundingRectWithSize 方法无法计算正确。如果您的属性适用于所有文本范围,则可以正常工作。但是由于您没有提到您希望它在您的问题中第一次应用于属性文本,所以您对我的回答投反对票是不公平的

标签: ios uitableview uiview uilabel


【解决方案1】:
+ (CGFloat)heightWithText:(NSString *)text
{
    SizingLabel.text = text;
    CGSize labelSize = [SizingLabel sizeThatFits:CGSizeMake(LABEL_WIDTH, CGFLOAT_MAX)];

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

【讨论】:

  • 如果为标签设置了字体,则适用于 UILabel。
  • @OlgaVogue 不,它只在某些时候有效。 sizeThatFits 是出了名的错误。
【解决方案2】:

下面的代码是计算动态文本长度的矩形(ios7版本)

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

得到矩形后,用它来计算单元格大小

----------------旧版本-------------------

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

【讨论】:

  • (NSDictionary)属性是您设置文本属性的地方
【解决方案3】:

在您的自定义单元类中执行此操作:

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

在主课中执行此操作..

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

就这样吧……

【讨论】:

    【解决方案4】:

    对于具有属性文本的 UILabel 的简单大小调整,我将此类别添加到 UILabel。

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

    需要注意的两点:

    1. 当不设置attributedText(而只是使用text)时,此方法不考虑numberOfLines 属性。
    2. boundingRectWithSize 返回分数的分数。如果您将此方法返回的值用于布局,您可能应该ceilf 宽度和高度。

    【讨论】:

      【解决方案5】:

      如上所述,sizeThatFits:(因此sizeToFit)不适用于UILabel 对象。

      您最好使用首选的textRectForBounds:limitedToNumberOfLines: 方法:

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

      【讨论】:

      • 对我也不起作用,您应该遵循命名约定并以小写开头的变量名(或者SizingLabel应该是一个类?)
      • SizingLabel一定是自动重命名问题。您或任何人也可以编辑帖子;)至于这不起作用。问题出在哪一部分?基本上这段代码只使用内置的textRectForBounds:limitedToNumberOfLines:,它应该总是有效的。
      • 它返回的大小并不能真正反映文本的大小。毕竟,它没有考虑字体。我最终使用了NSString boundingRectWithSize:options:attributes:context:
      • 它确实考虑了UILabel 字体和参数。您可以在 IB 中进行所有设置,然后进行准确的测量。这就是为什么我更喜欢它而不是尝试使用NSString 重新创建标签配置。至于您的问题,是内置方法返回错误值还是伴随调整? SizingLabel 来自原始问题。
      • 如果你相信this comment,当属性字符串不包含NSFontAttributeName时,它似乎无法正常工作。
      猜你喜欢
      • 2018-03-09
      • 2011-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多