【发布时间】:2021-01-18 13:10:08
【问题描述】:
所以我制作了自定义视图 ExpressionView 来可视化数学表达式。表达式的每一部分都是 UILabel 持有一个数字或操作,标签在 ExpressionView 内以右对齐的行对齐。我希望 ExpressionView 的宽度由外部的自动布局约束定义,但高度应该是固有的,这取决于我必须为给定宽度制作多少行标签。
对齐方法效果很好,我使用每个标签的 frame.size 和 ExpressionView 的宽度,进行数学运算,设置标签的框架位置,并计算包含所有行所需的高度。我还定义了这些,以便在每次 ExpressionLabel 的宽度发生变化时设置内在大小和重新布局标签:
override var intrinsicContentSize: CGSize {
let res = CGSize(width: UIView.noIntrinsicMetric,
height: CGFloat(self.contentHeight) //counted during self.layoutAllLabels()
)
return res
}
public override func layoutSubviews() {
super.layoutSubviews() //finish layout to get current label sizes and self width
let preHeight = self.contentHeight
self.layoutAllLabels() //layout all labels in current width, count required height
//if required height changed, relayout everything
if (preHeight != self.contentHeight) {
self.invalidateIntrinsicContentSize()
self.superview?.setNeedsLayout()
self.superview?.layoutIfNeeded()
}
}
当 ExpressionLabel 由普通 UIView 中的自动布局约束设置到位时,一切正常。但是当 ExpressionLabel 固定在 UITableViewCell 的 contentView 中时它会失败,我希望它能够定义单元格的高度。我的 UITableView 具有自动调整单元格大小所需的这些行
self.estimatedRowHeight = 50
self.rowHeight = UITableView.automaticDimension
单个单元格的大小以某种方式发生并且通常是正确的,但通常也会给出无效的高度。它可能与单元重用有关(通过 dequeueReusableCells()),因为旧的高度可能保留在重用的单元中。但是为什么它们没有更新,当它们应该在任何 ExpressionView.layoutSubviews() 调用中更新时?在 UITableView 中创建单元格时不会自动布局吗?如果没有,在哪里对我的标签进行布局,以便即使在 UITableView 中也能正确更新?当我知道最终的单元格宽度,并且可以根据它调整其子视图的固有高度时?
【问题讨论】:
-
您发布的几乎所有代码都是不必要的。您是否将单元设计为故事板原型?还是全部通过代码?显示完整单元类的代码。
-
因为我相信约束不是问题。我已经阅读了一些帖子,并且知道应该如何安排它们。我不知道在哪里放置ExpressionView的布局逻辑,这样我就已经知道最终宽度,但可以修改高度。这应该是可能的,因为简单的 UILabel 提供了相同的行为 - 您可以将 UILabel 放在单元格内,它会将其文本格式化为单元格的宽度,但根据文本的长度修改单元格的高度。我想对我的 ExpressionView 做同样的事情。
标签: ios swift uitableview autosize