在UITableViewCell上使用启用了多行和自动换行的UILabel时,UITableView可以毫无问题地处理不同的单元格高度。 UILabel根据其内容和宽度计算其高度。
我实现了一个自定义视图(https://github.com/fthdgn/ios-demo/blob/master/demo/CustomGridView.swift),该视图也根据其内容和宽度来计算其高度。该视图是一个简单的网格视图,它根据列数确定行数和高度,列数由可用宽度决定。但是,在UITableViewCell上使用自定义视图时会出现问题。
在我的演示应用程序(https://github.com/fthdgn/ios-demo)上,
- 在第一个选项卡[第一个图像]上,单独使用自定义视图。它的高度是正确的。 Button添加新项目并正确更新其高度。
- 在第二个选项卡[第二个图像]上,自定义视图的高度计算错误。该高度是根据XIB文件上视图的占位符宽度计算的。此宽度小于正确的宽度,因此高度大于正确的值。
- 第二个选项卡[第三张图像]上的重新加载按钮,重新加载表格。自定义视图会正确计算并自我更新。
- 在第3个选项卡[第4个图像]上,UILabel从一开始就根据可用宽度计算其高度。
为什么我的自定义视图不能像UILabel一样工作?是否缺少setNeedsLayout,invalidateIntrinsicContentSize调用?
我更新了代码,以在UITableView上仅显示包含11个单元格的一行。
由于所选设备为4S,因此XIB文件上的“网格视图”的宽度为300。我使用的模拟器是11 Pro Max,它比4S宽。
nativeContentSize和layoutSubviews调用将打印以下内容:
- 内容(-1.0,50.0)框架(300.0,0.5)
首先调用intrinsicContentSize。框架就是XIB上的
约束尚未调整视图的大小。此宽度需要50
放置细胞的高度。
- 布局(394.0,50.333333333333336)
调用布局时,高度是根据intrinsicContentSize确定的,宽度是由UITableViewCell约束确定的。然后,它比用于计算internalContentSize的值还要宽。
- 内容(-1.0,20.0)框架(394.0,50.333333333333336)
由于布局已更改,因此使invalidateContentSize无效。根据正确的宽度计算出新的internalContentSize值。新高度为20。
- 布局(394.0,50.333333333333336)
触发布局。即使最后一个internalContentSize.height是20,它仍然使用50。
- 内容(-1.0,20.0)框架(394.0,50.333333333333336)
布局使internalContentSize无效。重新计算了internalContentSize,但其值没有改变。
这些调用之后,尽管最后一个internalContentSize希望为20高度,但帧仍为50。您可以在第二个屏幕截图中看到,具有11个单元格的行比应有的长。