iOS 8 中的新功能,您可以通过简单地设置估计的行高来获得 100% 动态表格视图单元格,然后使用自动布局在单元格中布局您的元素。如果内容的高度增加,单元格的高度也会增加。这非常有用,我想知道是否可以为表格视图中的节标题完成相同的壮举?
例如,可以在 tableView:viewForHeaderInSection:
中创建一个 UIView
,添加一个 UILabel
子视图,针对视图指定标签的自动布局约束,并让视图增加高度以适应标签的内容,而无需实施tableView:heightForHeaderInSection:
?
viewForHeaderInSection
的文档指出:“此方法仅在 tableView:heightForHeaderInSection: 也实现时才能正常工作。”我还没有听说 iOS 8 是否有任何变化。
如果不能做到这一点,那么模仿这种行为的最佳方法是什么?
这个有可能。它是 iOS 8 中引入的动态单元格高度旁边的新功能。
为此,请对节标题高度使用自动尺寸,如果需要,您可以提供估计的节标题高度。这可以在选择表视图或以编程方式在 Interface Builder 中完成:
https://i.stack.imgur.com/u3YTv.png
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
,尤其是从上到下,这样高度可以由约束来确定。而已!
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
。
(我添加这个答案是因为第二段包含一个问题的答案,在阅读了一些可能会错过的所有评论后可以找到该问题。)
estimatedRowHeight
后,这就像魅力:)
陷入了同样的问题,即标题高度为零,除非我在委托中为 heighForHeaderInSection
提供固定高度。
尝试了很多解决方案,其中包括
self.tableView.sectionHeaderHeight = UITableView.automaticDimension
self.tableView.estimatedSectionHeaderHeight = 73
但没有任何效果。我的单元格也使用了正确的自动布局。通过使用以下代码,行正在动态改变它们的高度,但节标题没有。
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
}
斯威夫特 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
}
我试过了
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 25;
但它没有正确调整带有多行标签的标题。添加了这个来解决我的问题:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Recalculates height
tableView.beginUpdates()
tableView.endUpdates()
}
tableView:estimatedHeightForHeaderInSection
和 tableView:heightForHeaderInSection
,而不是在 viewDidLoad 中定义。
estimatedSectionHeaderHeight
就我而言:
以编程方式设置不起作用。
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension
。
在情节提要中设置不起作用。覆盖 heightForHeaderInSection 工作。
覆盖 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return UITableViewAutomaticDimension }
测试环境:
Mac OS 10.13.4
XCode 版本 9.4.1
模拟器 iPhone 8 Plus
是的,它对我有用。我必须进行更多更改,如下所示:
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let label = UILabel()
label.numberOfLines = 0
label.text = my own text
return label
}
斯威夫特 5,iOS 12+
它对我有用的唯一方法是
tableView.sectionHeaderHeight = UITableView.automaticDimension
tableView.estimatedSectionHeaderHeight = 40
tableView.estimatedRowHeight = 80
然后为自定义标题视图元素设置约束,以便自动布局引擎可以确定它们的 x、y 位置和行高。 IE
NSLayoutConstraint.activate([
titleLabel.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor),
titleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -24)
])
我修改了 iuriimoz answer。刚刚替换了 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 有“淡出”动画效果
UITableViewAutomaticDimension
的文档说“如果您在tableView:heightForHeaderInSection:
或tableView:heightForFooterInSection:
中返回此常量,则UITableView
使用适合从tableView:titleForHeaderInSection:
或tableView:titleForFooterInSection:
返回的值的高度(如果标题不是nil
)。”estimatedSectionHeaderHeight
或tableView:estimatedHeightForHeaderInSection:
ANDsectionHeaderHeight
或tableView:heightForHeaderInSection:
。此外,如果您使用委托方法,则必须为估计返回一个大于 1.00 的值(完全未记录的行为),否则高度的委托将不会被调用,并且将使用默认的表视图标题高度。