是否可以使用“自动布局”获得动态表格视图节标题高度?


112

iOS 8中的新增功能,您只需设置估计的行高即可获得100%动态表视图单元格,然后使用“自动布局”在单元格中布局元素。如果内容的高度增加,单元格的高度也会增加。这非常有用,并且想知道表视图中的节标题是否可以实现相同的功能?

例如,是否可以创建一个UIViewin tableView:viewForHeaderInSection:,添加一个UILabel子视图,针对视图指定标签的自动布局约束,以及使视图的高度增加以适合标签的内容,而无需实施tableView:heightForHeaderInSection:

有关viewForHeaderInSection状态的文档:“仅当还实现了tableView:heightForHeaderInSection:时,此方法才能正确工作。” 我还没有听说iOS 8是否有任何更改。

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

Answers:


274

这个有可能。它是iOS 8中实现的动态单元格高度的新增功能。

非常简单 只需将其添加到viewDidLoad

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

然后覆盖viewForHeaderInSection并使用“自动布局”将视图中的元素约束为合适的位置。而已!无需执行heightForHeaderInSection。而且实际上sectionHeaderHeight也不需要说明,我只是为了清楚起见添加了它。

请注意,在iOS 11中,默认情况下,单元格和页眉/页脚视图使用估计的高度。唯一要做的是提供一个估计的高度,以更好地告知系统预期的结果。默认值为,UITableViewAutomaticDimension但您应该提供更好的估计值,即如果可能的话,它们的平均高度。


3
如果可行,那很酷,但是文档没有提到它,如果我没记错的话,WWDC会话也没有。对于文档UITableViewAutomaticDimension说:“如果你在返回此常数tableView:heightForHeaderInSection:或者tableView:heightForFooterInSection:UITableView使用适合从返回的值的高度tableView:titleForHeaderInSection:或者tableView:titleForFooterInSection:(如果标题没有nil)。”
亚伦·布拉格

28
这对我不起作用。我的节标题能够自动计算高度,但是它与节中的单元格重叠。我正在使用xib文件设置标题视图,并在界面生成器中设置约束。那是我的问题吗?你们在哪里创建约束?谢谢!
CoBrA2168


10
这里的另一个关键点是,还需要对表格单元进行自动高度(UITableViewAutomaticDimension)计算的配置,以使其在各部分上起作用。
Bob Spryn

9
您必须具有estimatedSectionHeaderHeighttableView:estimatedHeightForHeaderInSection:AND sectionHeaderHeighttableView:heightForHeaderInSection:。此外,如果您使用委托方法,则必须为估算返回一个大于1.00的值(完全未记录的行为),否则,不会调用height的委托,并且将使用默认的表格视图标题高度。
瓦多夫

29

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

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

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


1
谢谢,设置后estimatedRowHeight像魅力一样工作:)
sz ashik

1
即使您没有对行使用UITableViewAutomaticDimension,也是如此。感谢您为我节省一个小时。
Ryan Romanchuk

14

陷入同一问题中,标头的高度一直为零,除非我为委托提供了固定的高度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 {
    UITableView.automaticDimension
}

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

11

迅捷4+

工作(经过100%测试)

如果您同时需要两个部分以及基于内容的具有动态高度的行,则可以使用以下代码:

在viewDidLoad()上编写以下行:

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

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

现在,我们使用UITableView Delegate方法设置行高和节高:

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

       return UITableView.automaticDimension

   }

注意这个好答案。从2020年开始,似乎只能使用viewDidLoad中的四个属性。
Fattie

注意这个好答案。从2020年开始,您确实需要两条“无用”的线条来给出估计的高度(例如20左右)。
Fattie

6

我试过了

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

但是它没有正确设置带有多行标签的标题的大小。添加此解决我的问题:

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

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

确实定义数据源功能tableView:estimatedHeightForHeaderInSectiontableView:heightForHeaderInSection而不是在viewDidLoad上定义。
基思·杨

我发现estimatedSectionHeaderHeight只有在iOS 11以下才需要设置
doctorBroctor

1

就我而言:

  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版本9.4.1
  • 模拟器iPhone 8 Plus

0

是的,它对我有用。我必须进行以下更改:

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

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

    return label
}

-2

我修改了iuriimoz的 答案。刚替换为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()
}

对于iOS 10

tableView.beginUpdates()
tableView.endUpdates()

对我的viewWillAppear具有“淡入淡出”动画效果

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.