如何解决带有表格视图和自定义表格视图单元格的iOS自动布局的谜团
https://github.com/mattneub/SelfSizingCells/tree/master
目标是在表格视图中获得自定义大小的单元格,该表格基于绘制自己的文本而不是UILabel的自定义视图。我可以做到,但是它涉及到一个奇怪的布局错误,我不明白为什么需要它。时间安排似乎有些问题,但后来我不明白为什么UILabel不会出现相同的问题。
为了演示,我将示例分为三个场景。
场景1:UILabel
在第一个场景中,每个单元格都包含一个UILabel,固定在内容视图的所有四个侧面上。我们要求自我调整大小的单元格,然后得到它们。看起来很棒。
场景2:StringDrawer
在第二个场景中,UILabel已被名为StringDrawer的自定义视图替换,该视图绘制了自己的文本。就像标签一样,它固定在内容视图的所有四个侧面。我们要求自定义大小的单元格,但是如何获得它们?
为解决此问题,我根据显示的字符串给StringDrawer一个intrinsicContentSize
。基本上,我们测量字符串并返回结果大小。特别是,高度将是此视图所需的最小高度,以便以该视图的当前宽度完整显示字符串,并且单元格的大小应为此设置。
class StringDrawer: UIView {
@NScopying var attributedText = NSAttributedString() {
didSet {
self.setNeedsdisplay()
self.invalidateIntrinsicContentSize()
}
}
override func draw(_ rect: CGRect) {
self.attributedText.draw(with: rect,options: [.truncatesLastVisibleLine,.usesLineFragmentOrigin],context: nil)
}
override var intrinsicContentSize: CGSize {
let measuredSize = self.attributedText.boundingRect(
with: CGSize(width:self.bounds.width,height:10000),context: nil).size
return CGSize(width: UIView.noIntrinsicmetric,height: measuredSize.height.rounded(.up) + 5)
}
}
但是出了点问题。在此场景中,一些初始单元格的底部有一些额外的空白。此外,如果将这些单元格从视图中滚动出来然后又重新回到视图中,则它们看起来是正确的。其他所有单元格看起来都很好。那证明我在做的事是正确的,那么为什么它不能用于初始单元格?
好吧,我已经做了一些繁重的日志记录,并且发现在最初为可见单元格调用intrinsicContentSize
时,StringDrawer尚未正确知道其自身的最终宽度,即自动布局后将具有。我们被称为太早了。我们使用的宽度太窄,因此返回的高度太高。
场景3:具有解决方法的StringDrawer
在第三个场景中,我为在第二个场景中发现的问题添加了一种解决方法。效果很好!但这太可怕了。基本上,在视图控制器中,我等到视图层次结构组装好后,再通过调用beginUpdates
和endUpdates
强制表视图进行另一轮布局。
var didInitialLayout = false
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if !didInitialLayout {
didInitialLayout = true
UIView.performWithoutAnimation {
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
}
}
神秘之物
好的,这是我的问题:
(1)是否有更好,更省心的解决方法?
(2)为什么我们完全需要这种解决方法?特别是为什么我们的StringDrawer遇到这个问题,而UILabel却不是?显然,UIlabel 确实足够早地知道其自身的宽度,以便在布局系统对其进行查询时,可以在第一遍正确给出自己的内容大小。为什么我的StringDrawer与此不同?为什么需要额外的布局通行证?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。