假设我在UILabel中有以下文本(一长行动态文本):

由于外星军队的数量远远超过了团队,玩家必须利用后世界末日的优势,比如在垃圾箱、柱子、汽车、瓦砾和其他物体后面寻找掩护。

我想调整UILabel的高度,这样文本就可以放进去了。我使用以下属性的UILabel,使文本内包装。

myUILabel.lineBreakMode = UILineBreakModeWordWrap;
myUILabel.numberOfLines = 0;

如果我的方向不对,请告诉我。谢谢。


当前回答

基于Swift 4及以上答案的UILabel扩展

extension UILabel {

    func retrieveTextHeight () -> CGFloat {
        let attributedText = NSAttributedString(string: self.text!, attributes: [NSFontAttributeName:self.font])

        let rect = attributedText.boundingRect(with: CGSize(width: self.frame.size.width, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, context: nil)

        return ceil(rect.size.height)
    }

}

可以这样使用:

self.labelHeightConstraint.constant = self.label.retrieveTextHeight()

其他回答

myLabel.text = "your very long text"
myLabel.numberOfLines = 0
myLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping

请在故事板中为可用性设置约束,包括左上右下

你的方向是对的。你所需要做的就是:

myUILabel.numberOfLines = 0;
myUILabel.text = @"Enter large amount of text here";
[myUILabel sizeToFit];

一行是克里斯的答案是错的。

newFrame.size.height = maximumLabelSize.height;

应该是

newFrame.size.height = expectedLabelSize.height;

除此之外,这是正确的解决方案。

斯威夫特2:

    yourLabel.text = "your very long text"
    yourLabel.numberOfLines = 0
    yourLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
    yourLabel.frame.size.width = 200
    yourLabel.frame.size.height = CGFloat(MAXFLOAT)
    yourLabel.sizeToFit()

有趣的是sizeToFit()将frame.size.height设置为最大浮动,这将为长文本提供空间,但sizeToFit()将强制它只使用必要的,但总是在设置.frame.size.height后调用它。

我建议为调试目的设置. backgroundcolor,这样你就可以看到为每个情况呈现的帧。

谢谢你写这篇文章。这对我帮助很大。在我的例子中,我也在一个单独的视图控制器中编辑文本。我注意到当我使用:

[cell.contentView addSubview:cellLabel];

在tableView:cellForRowAtIndexPath:方法中,每当我编辑单元格时,标签视图不断地在前一个视图之上呈现。文本变得像素化,当某些内容被删除或更改时,旧版本在新版本下可见。下面是我解决这个问题的方法:

if ([[cell.contentView subviews] count] > 0) {
    UIView *test = [[cell.contentView subviews] objectAtIndex:0];
    [test removeFromSuperview];
}
[cell.contentView insertSubview:cellLabel atIndex:0];

不再有奇怪的分层。如果有更好的处理方法,请告诉我。