字符串边界矩形计算的高度与 UITextView 内容高度不匹配



1具有带有大小尺寸的单元格的UITATIONVIEW。高度基于1所需显示的文本块,因此我需要测量文本。

1'MOUST只是使用一些Lorem文本:

"接力赛是开发人员,化妆周末巧克力足球,开发人员很重要。 每个胡萝卜讨厌任何EROS Carton跑步。ID毛里斯 宣传,很多东西都非常高兴。展示 想要Sapien,令人难过的营养需求,在其中进行了消毒。 Curabitur Layer Lake或Ultricies结束。为了方便起见,丑陋 作者纸箱,宣传本身开发人员洛雷姆,维塔·生态自由 巨大的温度。但是篮球仇恨和拉力直径。毛里斯 始终不要lorem varius潜水。Maecenas或DUI毕业。在这个 街道的类型。车辆的每个SAPIEN支出ID 需要玩家的时间。taciti班级就业 通过我们的婚姻,他的初学者。有些或关心 他希望,它成为累积的沙拉。每个ID Pot下午课程 但是,香蕉户外。零营养,怀孕 免费。"

当我调用ceil(text.height())时,它会返回386.0高,但是当我将该文本放入UITEXTVIEW并打印出UtextextExtView的内容大小时,它说内容为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开始调试之前更优雅(:

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'已验证了UITEXTVIEW使用的是Size 17的系统字体,该字体与上面的代码匹配。

1'已验证了UITEXTVIEW的框架(显示后(为(16.0, 45.0, 382.0, 385.6667),因此spaceAboveTextView=45是准确的,并且width=382是准确的。1还检查了UITEXTVIEW上的约束,它的底部约束为8pt,边距为8pt,在spaceBelowTextView中总计16pt。

那么,我在做什么错?

您很可能有问题,因为您忘记了对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

1刚刚测试了此解决方案,它对我有效的系统字体17。请告诉我是否不起作用!

测量在屏幕上显示的文本很困难,因为系统会更改字体和间距,从而使文本在CRT上更加清晰(例如,它可以替换屏幕字体作为向量字体( 。即使那样,当使用具有较高上升或下降的字符(如A.

(时,也可能存在一些重叠。

nsstring和nsastribatedStrings具有测量例程,可以计算当前图形上下文中文本的边界大小。请参阅boundingRectWithSize:选项:属性:。在过去的1年中,当1个没有方便的CGContext时强制栅格指标是创建一个小的屏幕外映射上下文(例如大小的1像素(,并在测量文本时将其设置为当前上下文。

您要寻找的另一件事是uitextview将其吸引到其textContainer而不是进入其框架中的事实。IIRC默认容器是插图的框架,由4或5像素。

最新更新