是否可以使用自动布局获得动态 table 视图部分 header 高度?
Is it possible to obtain a dynamic table view section header height using Auto Layout?
iOS8 中的新增功能,您只需设置估计的行高即可获得 100% 动态 table 视图单元格,然后使用自动布局在单元格中布局元素。如果内容的高度增加,单元格的高度也会增加。这非常有用,我想知道是否可以在 table 视图中对 headers 部分完成相同的壮举?
例如,可以在 tableView:viewForHeaderInSection:
中创建一个 UIView
,添加一个 UILabel
子视图,针对视图指定标签的自动布局约束,并增加视图高度以适合标签的内容,而无需实施 tableView:heightForHeaderInSection:
?
viewForHeaderInSection
的文档指出:"This method only works correctly when tableView:heightForHeaderInSection: is also implemented." 我还没有听说 iOS 8.
是否有任何变化
如果不能做到这一点,模仿这种行为的最佳方式是什么?
这是可能的。它与 iOS 8.
中引入的动态单元格高度一起是新的
为此,请为部分 header 高度使用自动尺寸标注,如果需要,您可以提供估计的部分 header 高度。这可以在选择 table 视图时在 Interface Builder 中完成,也可以通过编程方式完成:
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:)
并根据需要使用自动布局来限制视图。一定要完全约束到UITableViewHeaderFooterView
的contentView
,尤其是top-to-bottom,这样高度就可以由约束决定了。就是这样!
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
}
这可以通过在 table 视图上设置(或返回)estimatedSectionHeaderHeight
来完成。
如果您的部分 header 在设置 estimatedSectionHeaderHeight
后与您的单元格重叠,请确保您也使用了 estimatedRowHeight
.
(我添加这个答案是因为第二段包含一个问题的答案,可以在阅读所有可能会错过的评论后找到。)
我试过了
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 25;
但它的大小不正确 header 带有多行标签。
添加这个来解决我的问题:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Recalculates height
tableView.beginUpdates()
tableView.endUpdates()
}
我修改了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 有 "fade" 动画效果
是的,它适合我。我必须做出如下更多更改:
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let label = UILabel()
label.numberOfLines = 0
label.text = my own text
return label
}
就我而言:
- 以编程方式设置无效。
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension
.
在情节提要中设置无效。
覆盖 heightForHeaderInSection
有效。
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableViewAutomaticDimension
}
测试环境:
- Mac OS 10.13.4
- XCode 版本 9.4.1
- 模拟器iPhone8 Plus
陷入相同的问题,其中 header 的高度一直为零,除非我在委托中为 heighForHeaderInSection
.
提供固定高度
尝试了很多解决方案,其中包括
self.tableView.sectionHeaderHeight = UITableView.automaticDimension
self.tableView.estimatedSectionHeaderHeight = 73
但没有任何效果。我的手机也使用了适当的自动布局。使用以下代码动态更改行的高度,但 header 部分没有。
self.tableView.estimatedRowHeight = 135
self.tableView.rowHeight = UITableView.automaticDimension
修复非常简单也很奇怪,但我必须实现委托方法而不是 estimatedSectionHeaderHeight
和 sectionHeaderHeight
的 1 行代码,我的情况如下所示。
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 Delegate 方法设置了行高和节高:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableView.automaticDimension
}
Swift5,iOS12+
对我有用的唯一方法是
tableView.sectionHeaderHeight = UITableView.automaticDimension
tableView.estimatedSectionHeaderHeight = 40
tableView.estimatedRowHeight = 80
然后为自定义 header 视图元素设置约束,以便自动布局引擎可以确定它们的 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)
])
iOS8 中的新增功能,您只需设置估计的行高即可获得 100% 动态 table 视图单元格,然后使用自动布局在单元格中布局元素。如果内容的高度增加,单元格的高度也会增加。这非常有用,我想知道是否可以在 table 视图中对 headers 部分完成相同的壮举?
例如,可以在 tableView:viewForHeaderInSection:
中创建一个 UIView
,添加一个 UILabel
子视图,针对视图指定标签的自动布局约束,并增加视图高度以适合标签的内容,而无需实施 tableView:heightForHeaderInSection:
?
viewForHeaderInSection
的文档指出:"This method only works correctly when tableView:heightForHeaderInSection: is also implemented." 我还没有听说 iOS 8.
如果不能做到这一点,模仿这种行为的最佳方式是什么?
这是可能的。它与 iOS 8.
中引入的动态单元格高度一起是新的为此,请为部分 header 高度使用自动尺寸标注,如果需要,您可以提供估计的部分 header 高度。这可以在选择 table 视图时在 Interface Builder 中完成,也可以通过编程方式完成:
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:)
并根据需要使用自动布局来限制视图。一定要完全约束到UITableViewHeaderFooterView
的contentView
,尤其是top-to-bottom,这样高度就可以由约束决定了。就是这样!
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
}
这可以通过在 table 视图上设置(或返回)estimatedSectionHeaderHeight
来完成。
如果您的部分 header 在设置 estimatedSectionHeaderHeight
后与您的单元格重叠,请确保您也使用了 estimatedRowHeight
.
(我添加这个答案是因为第二段包含一个问题的答案,可以在阅读所有可能会错过的评论后找到。)
我试过了
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 25;
但它的大小不正确 header 带有多行标签。 添加这个来解决我的问题:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Recalculates height
tableView.beginUpdates()
tableView.endUpdates()
}
我修改了iuriimoz
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 有 "fade" 动画效果
是的,它适合我。我必须做出如下更多更改:
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let label = UILabel()
label.numberOfLines = 0
label.text = my own text
return label
}
就我而言:
- 以编程方式设置无效。
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension
.
在情节提要中设置无效。
覆盖
heightForHeaderInSection
有效。
override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return UITableViewAutomaticDimension }
测试环境:
- Mac OS 10.13.4
- XCode 版本 9.4.1
- 模拟器iPhone8 Plus
陷入相同的问题,其中 header 的高度一直为零,除非我在委托中为 heighForHeaderInSection
.
尝试了很多解决方案,其中包括
self.tableView.sectionHeaderHeight = UITableView.automaticDimension
self.tableView.estimatedSectionHeaderHeight = 73
但没有任何效果。我的手机也使用了适当的自动布局。使用以下代码动态更改行的高度,但 header 部分没有。
self.tableView.estimatedRowHeight = 135
self.tableView.rowHeight = UITableView.automaticDimension
修复非常简单也很奇怪,但我必须实现委托方法而不是 estimatedSectionHeaderHeight
和 sectionHeaderHeight
的 1 行代码,我的情况如下所示。
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 Delegate 方法设置了行高和节高:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableView.automaticDimension
}
Swift5,iOS12+
对我有用的唯一方法是
tableView.sectionHeaderHeight = UITableView.automaticDimension
tableView.estimatedSectionHeaderHeight = 40
tableView.estimatedRowHeight = 80
然后为自定义 header 视图元素设置约束,以便自动布局引擎可以确定它们的 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)
])