是否可以使用自动布局获得动态表视图部分标题高度?

在 iOS8中,您可以通过简单地设置估计的行高来获得100% 的动态表格视图单元格,然后使用 Auto Layout 在单元格中布局您的元素。如果内容的高度增加,单元格的高度也会增加。这是非常有用的,我想知道是否同样的壮举可以完成表视图中的节标题?

例如,是否可以在 tableView:viewForHeaderInSection:中创建一个 UIView,添加一个 UILabel子视图,针对视图为标签指定自动布局约束,并使视图的高度增加以适应标签的内容,而不必实现 tableView:heightForHeaderInSection:

viewForHeaderInSection的文档声明: “此方法只有在 tableView: heightForHeaderInSection: 也实现时才能正常工作。”我还没听说 iOS8有什么变化。

如果一个人不能做到这一点,那么模仿这种行为的最佳方式是什么?

91520 次浏览

这是可能的,它是新的,就在 iOS8中引入的动态单元高度旁边。

要做到这一点,使用自动尺寸的部分标题高度,如果需要,您可以提供一个估计的部分标题高度。这可以在选择表视图或以编程方式进行 Interface Builder 操作时完成:

Table view configuration in storyboard

tableView.sectionHeaderHeight = UITableView.automaticDimension
tableView.estimatedSectionHeaderHeight = 38


//You can use tableView(_:heightForHeaderInSection:) and tableView(_:estimatedHeightForHeaderInSection:)
//if you need to support different types of headers per section

然后实现 tableView(_:viewForHeaderInSection:)并使用自动布局来按照需要约束视图。一定要完全约束到 UITableViewHeaderFooterViewcontentView,特别是从上到下,以便高度可以由约束确定。就是这样!

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UITableViewHeaderFooterView()
headerView.translatesAutoresizingMaskIntoConstraints = false
headerView.backgroundView = {
let view = UIView()
view.backgroundColor = myCustomColor
return view
}()


let headerLabel = UILabel()
headerLabel.translatesAutoresizingMaskIntoConstraints = false
headerLabel.text = "Hello World"
headerView.contentView.addSubview(headerLabel)
    

NSLayoutConstraint.activate([
headerLabel.leadingAnchor.constraint(equalTo: headerView.contentView.leadingAnchor, constant: 16),
headerLabel.trailingAnchor.constraint(equalTo: headerView.contentView.trailingAnchor, constant: -16),
headerLabel.topAnchor.constraint(equalTo: headerView.contentView.topAnchor, constant: 12),
headerLabel.bottomAnchor.constraint(equalTo: headerView.contentView.bottomAnchor, constant: -12)
])
    

return headerView
}

这可以通过在表视图上设置(或返回) estimatedSectionHeaderHeight来实现。

如果在设置 estimatedSectionHeaderHeight 之后,部分标题与单元格重叠,请确保也使用了 estimatedRowHeight

(我添加这个答案是因为第二段包含了一个问题的答案,这个问题可以在阅读了所有可能被忽略的评论之后找到。)

我尽力了

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 25;

但它没有正确的大小头与多行标签。 为了解决我的问题,我添加了以下内容:

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)


// Recalculates height
tableView.beginUpdates()
tableView.endUpdates()
}

我修改了 伊里莫兹 回答,只是替换了 viewWillAppear 方法:

tableView.sectionHeaderHeight = UITableViewAutomaticDimension
tableView.estimatedSectionHeaderHeight = 25




override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)


// Recalculates height
tableView.layoutIfNeeded()
}

还要将 tableView.layoutIfNeeded ()添加到

override func viewDidAppear(_ animated: Bool) {


super.viewDidAppear(animated)
tableView.layoutIfNeeded()
}

IOS10操作系统

tableView.beginUpdates()
tableView.endUpdates()

有“淡出”的动画效果在 viewWillAppear 为我

是的,它对我很有效。我必须做出以下更多的改变:

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let label = UILabel()


label.numberOfLines = 0
label.text          = my own text


return label
}

就我而言:

  1. 以编程方式设置。

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension.

  1. 以故事板 不是工作为背景。

  2. 重写 heightForHeaderInSection 成功了

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableViewAutomaticDimension
}

测试环境:

  • Mac OS 10.13.4
  • XCode Version 9.4.1
  • 模拟 iPhone 8 Plus

陷入了相同的问题,其中标题得到零高度,直到,除非我提供了一个固定的高度为 heighForHeaderInSection的委托。

尝试了很多解决方案,其中包括

self.tableView.sectionHeaderHeight = UITableView.automaticDimension
self.tableView.estimatedSectionHeaderHeight = 73

但都没用。我的手机也使用了正确的自动设置。通过使用下面的代码,行可以动态地改变高度,但是部分标题没有改变。

self.tableView.estimatedRowHeight = 135
self.tableView.rowHeight = UITableView.automaticDimension

修复是非常简单和怪异的太,但我必须实现的代理方法,而不是1行代码的 estimatedSectionHeaderHeightsectionHeaderHeight,这是为我的情况下。

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


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

Swift 4 +

工作(测试100%)

如果您需要这两个部分以及基于内容的动态高度行,那么您可以使用以下代码:

在 viewDidLoad ()上写下这几行:

    self.globalTableView.estimatedRowHeight = 20
self.globalTableView.rowHeight = UITableView.automaticDimension


self.globalTableView.sectionHeaderHeight =  UITableView.automaticDimension
self.globalTableView.estimatedSectionHeaderHeight = 25;

现在我们已经通过使用 UITableView 委托方法设置了行高和节高:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {


return UITableView.automaticDimension


}

Swift 5,iOS 12 +

唯一对我有效的方法就是

tableView.sectionHeaderHeight = UITableView.automaticDimension
tableView.estimatedSectionHeaderHeight = 40
tableView.estimatedRowHeight = 80

然后为自定义头视图元素设置约束,以便自动布局引擎可以确定它们的 x、 y 位置和行高。也就是说

NSLayoutConstraint.activate([
titleLabel.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor),
titleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -24)
])

还有一个变种

  1. estimatedHeightForFooterInSection
public func tableView(_ tableView: UITableView, estimatedHeightForFooterInSection section: Int) -> CGFloat {
return UITableView.automaticDimension
}
  1. heightForFooterInSection
public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return UITableView.automaticDimension
}