【问题标题】:Calculating multiline text height for UILabel/UITableViewCell: different results when calculating vs actual drawing为 UILabel/UITableViewCell 计算多行文字高度:计算与实际绘图时的不同结果
【发布时间】:2025-12-04 11:05:03
【问题描述】:

这里已经多次询问过这个一般性主题:如何使用不同数量的文本和不同的高度来渲染 UITableViewCells。规范的答案是:您使用 sizeWithFont:constrainedToSize:lineBreakMode: 在 heightForRowAtIndexPath 中计算表视图控制器委托中的高度。稍后,单元格被绘制出来,如果需要,您可以使用 [label sizeToFit] 之类的东西,所有这些都像魔术一样工作。

我的问题:我正在包装一些单元格,因为 sizeWithFont: 返回与实际绘图不同的尺寸。

一个具体的例子:

文字是这样的:“人们忘记了@BillGates 早在 1993 年就有一块来自 NEC 的 1/4 英寸厚的性感石板。本周发生的一切都与硬件无关!”

CGSize theSize = [text sizeWithFont:[UIFont systemFontOfSize:17.0f] constrainedToSize:CGSizeMake(310.0f, FLT_MAX) lineBreakMode:UILineBreakModeWordWrap];
NSLog(@"calculated size for %@: %f, %f",text, theSize.width, theSize.height);

这将返回:306.000000、84.000000。 (即 4 行,字体为 17px,行距为 4px,行距为 21px。)很好。

但是,稍后在实际绘制单元格时:

label = (UILabel *)[cell viewWithTag:3];
label.text = [NSString stringWithFormat:@"%@", text];
label.lineBreakMode = UILineBreakModeWordWrap;
label.font = [UIFont systemFontOfSize:17.0f];
CGSize labelSize;   
labelSize = label.frame.size;
NSLog(@"label size before resizing: %f, %f", labelSize.width, labelSize.height);
[label sizeToFit];
labelSize = label.frame.size;
NSLog(@"label size after resizing: %f, %f for text %@", labelSize.width, labelSize.height,text);

(UILabel 作为 UITableViewCell 的一部分从 NIB 加载。在 IB 中,我将其设置为 310px 宽。)

这应该返回与上面完全相同的大小。相反,我得到 281.000000, 105.000000 作为 sizeToFit 调用后的尺寸。现在在绘制时是 5 行而不是 4 行,并且文本溢出,我在 UI 中看到溢出。

因此,对于相同的文本,我计算了两个不同的维度,但无法计算出来。是关于 UILabel 的吗?它有一些内边距吗?对于某些文本,这种情况一直在发生,而在其他文本中则没有,而且我还没有将其追溯到有关字符串的特定内容;似乎是随机的。 This topic 强调有两个处理过程:计算高度与实际绘图。这与我所看到的一致。但我不明白到底发生了什么或如何解决它。

问题:为什么我看到两种不同的计算尺寸,我该如何解决?

【问题讨论】:

    标签: iphone uitableview uilabel


    【解决方案1】:
     titleSize = [title sizeWithFont:[UIFont systemFontOfSize:(CGFloat)17.0]
                                    constrainedToSize:CGSizeMake(280, 2000)
                                        lineBreakMode:NSLineBreakByWordWrapping];
    

    【讨论】:

      【解决方案2】:

      当然,发帖后30秒的解决方法就很明显了。也许对其他人也有用...

      sizeWithFont: 的大小是正确的。我以上述方式计算的尺寸不正确,因为[label sizeToFit] 减少了标签框架的宽度。在随后对相同代码的调用中,它从可能已经减少的帧开始。

      解决方法是简单地将框架 width 重置为已知的合适宽度,然后再调整大小以适应:

      CGRect labelFrame = label.frame;
      labelFrame.size.width = 310;
      label.frame = labelFrame;
      [label sizeToFit];
      

      【讨论】:

      • 谢谢,这正是我想要的:CGSize labelSize; labelSize = UILabelName.frame.size; ==> labelSize.height
      【解决方案3】:

      多行标签需要设置

      cell.textLabel.numberOfLines = 0;
      

      然后

      [cell.textLabel sizeToFit];
      

      但要获得漂亮的视图,您需要添加一些填充像素。你的应用会很棒!

      【讨论】: