字符串boundingRect计算出的高度不匹配的UITextView内容高度

问题描述:

1具有可变大小的细胞一个UITableView。高度是基于文本的块上需要显示,使得1只1需要测量的文本。字符串boundingRect计算出的高度不匹配的UITextView内容高度

1'm只是用一些Lorem存有文字

“没有竞争,化妆周末巧克力片,比如大开发商。 地址不会有任何仇恨花生药丸循环。Mauris南 宣传,房地产该集是很重要的,这是非常紧张的。目前 户外SAPIEN,三重和营养需要的魔法吧。 聊天层的湖泊和ultricies目的。优点丑陋,但 笔者丸,宣传,开发商LOREM,客户免费 它需要很大的温度,但是他讨厌篮球和拉直径。摩尔 总是多变LOREM不在乎。保护者PORTA DUI lectus。这 书签。每一个明智的,如果车辆 的价格需要它,在一个时间的球员。类由我们的婚姻开始就业扭曲 ,每himenaeos。最新的护理 想让一层沙拉。 Quisque ID乌仁娜blandit,治疗 的过程中的sed,aliquet eget velit乌仁娜metus。继电器相同狙击,未怀孕,也 时间*。“

1时调用ceil(text.height())返回386.0高,但是当1把文本到UITextView的,并打印出的UITextView的内容大小,它说的422.0含量高。(即我的文字被截断,因为UITextView的不足够高,能够显示的一切。)

为什么是有区别吗?使用下列字符串扩展计算

1'm文本的高度

extension String { 

    func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat { 
     let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude) 
     let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil) 

     return boundingBox.height 
    } 

} 

然后在tableView(heightForRowAt:) 1计算文本的高度,并把它添加到以上的空间和TextView的获得完整的细胞高度以下(这是更优雅1日开始调试这个前):

let textviewWidth = self.view.frame.size.width-CGFloat(32) 
let spaceAboveTextView = CGFloat(45) 
let spaceBelowTextView = CGFloat(16) 
let textHeight = ceil(text.height(withConstrainedWidth: textviewWidth, font: UIFont.systemFont(ofSize: 17.0))) 
let height = spaceAboveTextView + textHeight + spaceBelowTextView 

1've验证了的UITextView使用的17系统字体大小,其与上述我的代码相匹配。

1've验证的UITextView的帧(被显示之后)是(16.0, 45.0, 382.0, 385.6667)所以spaceAboveTextView=45是准确和width=382是准确的。 1've还检查在UITextView中的约束和它具有的8磅至限底部约束和余量是用于spaceBelowTextView共8PT 16PT的为好。

那么,什么是1做错了什么?

+0

澄清:您是否使用UITextView来支持多行文本。如果是这样,重构使用UILabel。只需将行数设置为0并设置您的约束。如果没有其他需要,将UITextView设置为不滚动应该使其像任何其他视图一样自我尺寸。 –

+0

我正面临同样的问题。你找到解决方案吗? – derpoliuk

+0

使用此代码确实帮助我计算正确的高度:https://*.com/q/32613836/1226304 – derpoliuk

用于在屏幕上显示文本MEASURING是困难的,因为系统改变字体和间距和例如以使文本在CRT上(例如,它可以代替矢量字体屏幕字体)更清晰。即使如此,它可能有一些重叠,使用字符高上升或下降就好了。

NSAttributedStrings具有的NSString和测量例程计算当前图形上下文文本的边界大小。见boundingRectWithSize:options:attributes:context:。在过去,当我没有方便的CGContext时,我所做的强制栅格度量标准是创建一个小的离屏位图上下文(例如,大小为1像素),并在测量文本时将其设置为当前上下文。

你想要寻找的另一件事是UITextView将其绘制到它的textContainer而不是它的框架。 IIRC默认容器是由4或5像素插入的帧。

最有可能你有一个问题,因为你忘了考虑textContainerInset(也可能是其他文本视图的插页)。

默认情况下,它们从顶部,左侧和右侧是8个。

尝试你的代码改成这样:

let textviewWidth = self.view.frame.size.width-CGFloat(32)-textView.textContainerInset.left-textView.textContainerInset.right 
let spaceAboveTextView = CGFloat(45)+textView.textContainerInset.top 
// bottom space is 0 by default. But lets add it just in case ;) 
let spaceBelowTextView = CGFloat(16)+textView.textContainerInset.bottom 
let textHeight = ceil(text.height(withConstrainedWidth: textviewWidth, font: UIFont.systemFont(ofSize: 17.0))) 
let height = spaceAboveTextView + textHeight + spaceBelowTextView 

我只是测试这个解决方案,它为我的作品与系统字体大小17.请让我知道,如果这行不通!

+1

我以前看过contentInsets,但它们都是零,我看着textContainer,但没有看到textContainerInsets。这些人占了16个点,所以这肯定有帮助,但我仍然在某个地方失去了一些东西。 –

+0

这个解决方案有助于缩短字符串,但长度较长的字符串在高度上的差异很大(在约1700字的字符串中,超过250个字符) – derpoliuk