UITableView 中多行 UILabel 的动态高度 header

Dynamic height of header with multiline UILabel in UITableView

我找到了通过设置

在 UITableView 中获取动态 header 高度的解决方案
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return UITableView.automaticDimension
}

func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
    return UITableView.automaticDimension
}

我得到的效果是 header 设置为一个 UILabel 行的高度,而它应该设置为所有行的高度。 我在 Horizo​​ntalStackView 中有两个 UILabel。当其中一个 UILabel 的长度超过一行时,自动高度调整将不起作用。我试过设置

tableView.beginUpdates()
tableView.endUpdates()

在一些启动方法中,但没有任何效果。

第 1 步:用 heightForHeaderInSection 方法计算两个 UILabel 文本的高度。

第 2 步:return heightForHeaderInSection 中的最大高度。

并确保将 UILabelnumberOfLines 属性 设置为 0。

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    let font = UIFont.systemFont(ofSize: 23)
    let height1 = "section \(section) label1 text".height(withConstrainedWidth: UIScreen.main.bounds.width/2 , font: font)  
    let height2 =  "section \(section) label2 text".height(withConstrainedWidth: UIScreen.main.bounds.width/2 , font: font) 
    return max(height1,height2)
}

这里我使用 String 的扩展名来计算 UILabel 文本的高度。

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: [NSAttributedString.Key.font: font], context: nil)
    
        return ceil(boundingBox.height)
    }
}

假设您已经使用 XIB 文件设置了第 Header 部分,这可能是一个约束问题,导致不正确的大小等等。

我列出了使用动态部分时可能发生的常见错误列表 headers。请检查它们 one-by-one,看看哪个解决了您的问题。

1。确保您的约束设置正确。

打开您的 Header XIB 部分,并确保有足够的约束 UITableView 来计算视图的高度。请注意,我已经设置了优先级为 999 的底部约束。这很重要,因为第 3 步。

2。确保您的 UILabel 可以成长

将两个 UILabel 的“行数”设置为零,如下所示。

3。调整内容拥抱和压缩阻力

Select 您的 UILabel,然后单击“尺寸检查器”()。

在底部,将这些值设置为 1000,以便自动布局将它们视为与其他约束一样重要。

  • 内容拥抱优先级 > 垂直

这会设置 UILabel 的高度与其文本内容相匹配的程度。

  • 抗压优先>垂直

这设置了 UILabel 应该阻止将其高度缩小到超出其内容高度的程度。

像这样:

4。 Return estimatedHeightForHeaderInSection

中的合理值
func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
    return 44.0
}

5。编译并 运行!

您的部分 headers 现在应该调整大小了。

备注:

  1. 确保您的数据源不是不依赖于部分索引的随机文本。

  2. 如果您的部分 headers 重叠或大小不当,请确保在 UITableView 滚动时您的数据源没有发生变化。