boundingRectWithSize 为多行标签返回错误的高度值
Posted
技术标签:
【中文标题】boundingRectWithSize 为多行标签返回错误的高度值【英文标题】:boundingRectWithSize returning a wrong height value for a multiline label 【发布时间】:2016-02-10 16:43:51 【问题描述】:boundingRectWithSize
和使用 Swift 语言的多行 UILabel 遇到了一个奇怪的问题。我目前在 Xcode 游乐场工作,因此可以实时查看 UI 的结果和更新。
我要做的是根据它的内容动态计算给定的 UILabel 高度,我知道这已经在其他 *** 问题中讨论过,但这对我来说似乎太奇怪了。
多行标签以NSAttributedString
形式包含此文本。文本是一个简单的 Lorem ipsum 占位符:
Lorem ipsum dolor sit amet,consectetur adipiscing elit。 Donec a diam lectus。 Sed 坐 amet ipsum mauris。 Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit。 Donec et mollis dolor。
这是UILabel
的代码:
let valueString = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor."
var dataValue = UILabel()
dataValue.numberOfLines = 0
dataValue.lineBreakMode = .ByWordWrapping
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .Justified
paragraphStyle.lineBreakMode = .ByWordWrapping
paragraphStyle.firstLineHeadIndent = 0.1
let attributedText = NSAttributedString.init(
string:valueString,
attributes:[NSParagraphStyleAttributeName:paragraphStyle, NSFontAttributeName:dataValue.font])
let textString = dataValue.text! as NSString
dataValue.attributedText = attributedText
dataValue.frame = CGRect(
x:CGFloat(kMargin),
y:dataType.frame.origin.y + CGFloat(kLabelHeight),
width:CGFloat((maxLabelWidth) - kMargin * 2),
height:textString.boundingRectWithSize(
CGSizeMake(CGFloat(kMaxWidth), CGFloat.max),
options:[.UsesLineFragmentOrigin, .UsesFontLeading],
attributes:[NSParagraphStyleAttributeName:paragraphStyle, NSFontAttributeName:dataValue.font],
context:nil).size.height)
问题在于 UILabel 只显示 3 行文本,停在文本的 mauris 单词处并截断最后一行,正如您从 Playground 预览功能中看到的那样:
【问题讨论】:
【参考方案1】:一个明显的问题是valueString
和textString
是两个不同的字符串。所以没有理由相信您放入标签的字符串与您正在测量的字符串相同。
你在这里使用valueString
:
let attributedText = NSAttributedString.init(
string:valueString, // ...
但你在这里使用dataString
:
height:textString.boundingRectWithSize(
另外,不要尝试将标签属性与属性文本结合起来。这可能会导致各种问题。 dataValue
标签应该没有font
。您不应该获取此 font
值。使用属性字符串做所有事情。你不应该构建两个不同风格的字典;您应该分配和测量完全相同的属性字符串。
换句话说,无论有无属性,都不要测量valueString
或textString
。测量attributedString
。
最后,确保标签的宽度与您在测量期间使用的宽度相同。你在说
CGSizeMake(CGFloat(kMaxWidth) // ...
但没有证据表明标签本身会具有这个宽度。
【讨论】:
你好@matt 谢谢你的回答,我已经更新了我的问题,明确表示我正在阅读相同的文本值 不,你没有。我在您的问题中没有看到关于textString
可能是什么的信息。
好吧,现在您只是在更改您的代码。所以现在我不相信你说的是你的代码真的是你的代码。 :)
是的,我知道,你是对的,所以我正在更新它以更好地模拟这里的真实情况,我第一次写问题时没有正确复制粘贴我的代码。现在可以看看吗?以上是关于boundingRectWithSize 为多行标签返回错误的高度值的主要内容,如果未能解决你的问题,请参考以下文章
调用 NSAttributedString.boundingRectWithSize 时应用程序崩溃
boundingRectWithSize 有时会返回大约 1 行高的高度
boundingRectWithSize:options:attributes:context用法
adjustsFontSizeToFitWidth 或 boundingRectWithSize 何时更改 context.actualScaleFactor?