关于开发中一些问题的记录。
如下图所示,《活动:一起聊聊动物世界》这个信息流Cell的标题,本应换行的Label内容直接被截断了,并且上下空白太多。
Debug
- 首先尝试在不同系统同一机型上进行Debug,发现4.7英寸屏幕从iOS8到iOS12.1都未出现该问题,暂时排除系统版本导致Bug。
- 尝试不同机型,发现5.5英寸和5.8英寸屏都出现了内容被截断的现象,由于界面采用比例布局,初步判定是在动态计算Label高度时出现的精度问题(float类型在计算时会四舍五入)
- 尝试在界面
layoutSubview
以后,对Label进行sizeToFit
操作,结果如图
- 看起来成功了,但这样的操作似乎是运气好,实际上是存在问题的,此时Cell的高度已经确定,我们只是强制改变了标题Label的frame,而Cell的高度并没有改变。并且如果Label添加了autolayout约束,那么sizeToFit会失效
- 优化为使用
sizeThatFits
拿到最优布局信息后更新约束,这样信息流Cell的自适应高度也会更新为理想高度
1 | CGSize labelSize = [self.titleLabel sizeThatFits:CGSizeMake(self.titleLabel.frame.size.width, MAXFLOAT)]; |
问题
- 猜测系统UILabel进行布局时,使用了NSString的
boundingRectWithSize:
方法。在计算出排版高度时,由于是float类型可能存在四舍五入等情况,最后存在的误差导致UILabel显示不全,上下空白太多 - 网络上有一些解决方案,例如
boundingRectWithSize:
计算出结果后取整再+1,这样的做法个人认为不够优雅,它并不是UILabel渲染的理想值,推荐使用sizeThatFits:
关于sizeThatFits和sizeToFit
sizeToFit
方法会计算最适合内容的宽度和高度,并会直接作用于调用对象framesizeThatFits:
方法会计算最适合内容的宽度和高度,但是不会直接作用于对象sizeThatFits:
方法计算的值是理想值