Swift - tableView 行高仅在滚动或切换后更新 expand/collapse
Swift - tableView Row height updates only after scrolling or toggle expand/collapse
我正在使用 CollapsibleTableView from here and modified it as per my requirement to achieve collapsible sections. Here is how it looks now。
由于根据 UI 设计,我的部分有边框,因此我选择 header 部分作为我的 UI 元素,它在折叠和展开时都保存数据模式。
原因:我试过了,但无法在下面解释的这个模型中工作 -
** 在 header 节中包含我的 header 元素,并在其单元格中包含每个项目的详细信息。默认情况下,该部分处于折叠状态。当用户点击 header 时,单元格会切换显示。正如我所说,由于需要向整个部分(点击 header 及其单元格)显示一个边框,我选择 header 部分作为我的 UI 操作元素。这是我的 tableView -
代码
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections.count
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
switch indexPath.row {
case 0:
return sections[indexPath.section].collapsed! ? 0 : (100.0 + heightOfLabel2!)
case 1:
return 0
case 2:
return 0
default:
return 0
}
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = self.tableView.dequeueReusableHeaderFooterViewWithIdentifier("header") as! CollapsibleTableViewHeader
if sections.count == 0 {
self.tableView.userInteractionEnabled = false
header.cornerRadiusView.layer.borderWidth = 0.0
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
header.amountLabel.hidden = true
header.titleLabel.text = "No_Vouchers".localized()
}
else {
header.amountLabel.hidden = false
header.cornerRadiusView.layer.borderWidth = 1.0
self.tableView.userInteractionEnabled = true
header.titleLabel.text = sections[section].name
header.arrowImage.image = UIImage(named: "voucherDownArrow")
header.setCollapsed(sections[section].collapsed)
let stringRepresentation = sections[section].items.joinWithSeparator(", ")
header.benefitDetailText1.text = stringRepresentation
header.benefitDetailText2.text = sections[section].shortDesc
header.benefitDetailText3.text = sections[section].untilDate
header.section = section
header.delegate = self
if sections[section].collapsed == true {
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
}
else {
if sections[section].isNearExpiration == true {
header.benefitAlertImage.hidden = false
header.benefitAlertText.hidden = false
}
else {
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
}
}
if appLanguageDefault == "nl" {
self.totalAmountLabel.text = "€ \(sections[section].totalAvailableBudget)"
}
else {
self.totalAmountLabel.text = "\(sections[section].totalAvailableBudget) €"
}
}
return header
}
切换函数collapse/expand -
我在该部分内使用 "dynamically changing" UI 标签的高度值,然后使用这些值来扩展边框(使用其布局约束)。
func toggleSection(header: CollapsibleTableViewHeader, section: Int) {
let collapsed = !sections[section].collapsed
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
// Toggle collapse
sections[section].collapsed = collapsed
header.setCollapsed(collapsed)
// Toggle Alert Labels show and hide
if sections[section].collapsed == true {
header.cornerRadiusViewBtmConstraint.constant = 0.0
header.cornerRadiusViewTopConstraint.constant = 20.0
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
}
else {
heightOfLabel2 = header.benefitDetailText2.bounds.size.height
if sections[section].isNearExpiration == true {
header.benefitAlertImage.hidden = false
header.benefitAlertText.hidden = false
header.cornerRadiusViewBtmConstraint.constant = -100.0 - heightOfLabel2!
header.cornerRadiusViewTopConstraint.constant = 10.0
if let noOfDays = sections[section].daysUntilExpiration {
if appLanguageDefault == "nl" {
header.benefitAlertText.text = "(nog \(noOfDays) dagen geldig)"
}
else {
header.benefitAlertText.text = "(valable encore \(noOfDays) jour(s))"
}
}
}
else {
header.cornerRadiusViewBtmConstraint.constant = -80.0 - heightOfLabel2!
header.cornerRadiusViewTopConstraint.constant = 20.0
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
}
}
// Adjust the height of the rows inside the section
tableView.beginUpdates()
for i in 0 ..< sections.count {
tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: i, inSection: section)], withRowAnimation: .Automatic)
}
tableView.endUpdates()
}
问题:
根据某些条件,我需要在首次启动视图时默认展开此 table 视图中的几个 headers 部分。当我计算标签的高度并使用高度设置边框的顶部和底部约束时,很难按照设计显示扩展部分 header。
由于我的UI标签的高度默认为 21,因此内容超出了边框。
UPDATE:行高仅在滚动视图后或在 collapse/expand
之间切换时发生变化
问题:
如何在第一次启动视图时计算 UI 部分 header 中显示的标签的高度? (这意味着,在我的 REST 调用完成后,将获取数据,然后我需要获取 UI 标签高度)。
目前,我正在使用heightOfLabel2 = header.benefitDetailText2.bounds.size.height
(或)
有没有更好的方法来实现这个?
提前致谢!
您可以试试这个字符串扩展来计算边界矩形
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: [NSFontAttributeName: font], context: nil)
return boundingBox.height
}
}
来源:
如果我对你的问题的理解正确,你要做的是在调用 toggleSection
.
时调整 tableHeaderView
的大小
因此,您 tableHeaderView
需要做的是调整大小
// get the headerView
let headerView = self.tableView(self.tableView, viewForHeaderInSection: someSection)
// tell the view that it needs to refresh its layout
headerView?.setNeedsDisplay()
// reload the tableView
tableView.reloadData()
/* or */
// beginUpdates, endUpdates
基本上你要做的是将上面的代码片段放在你的函数中 toggleSection(header: CollapsibleTableViewHeader, section: Int)
func toggleSection(header: CollapsibleTableViewHeader, section: Int) {
...
// I'm not sure if this `header` variable is the headerView so I'll just add my code snippet at the bottom
header.setNeedsDisplay()
/* code snippet start */
// get the headerView
let headerView = self.tableView(self.tableView, viewForHeaderInSection: someSection)
// tell the view that it needs to refresh its layout
headerView?.setNeedsDisplay()
/* code snippet end */
// reload the tableView
// Adjust the height of the rows inside the section
tableView.beginUpdates()
// You do not need this
for i in 0 ..< sections.count {
tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: i, inSection: section)], withRowAnimation: .Automatic)
}
// You do not need this
tableView.endUpdates()
}
解释:tableView 的 headerView/footerView 不会更新其布局,即使您调用 reloadData()
和 beginUpdates,endUpdates
。您需要先告诉视图它需要更新,然后再刷新 tableView
最后你还需要应用这两个代码
func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
return estimatedHeight
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableViewAutomaticDimension
}
以下是我根据对 OP 总体目标的理解所做的工作。如果我误解了,下面仍然是一个工作示例。完整的工作项目也在下面链接。
目标:
- 动态大小的 TableViewCells 也是
- 可折叠到 show/hide 其他详细信息
我尝试了多种不同的方法,这是我唯一可以开始工作的方法。
概览
设计使用了以下内容:
- 自定义 TableViewCells
- 自动布局
- TableView 自动维度
因此,如果您不熟悉这些(尤其是自动版式),可能需要先复习一下。
动态 TableViewCells
界面生成器
布置您的原型单元格。增加行高大小是最简单的。简单地从几个元素开始,以确保您可以让它正常工作。 (尽管添加到 Autolayout 中可能会很痛苦)。例如,简单地垂直堆叠两个标签,布局的整个宽度。为 "title" 制作顶部标签 1 行,为 "details"
制作第二个 0 行
重要提示:要将标签和文本区域配置为增长到其内容的大小,您必须将标签设置为 0 行并将文本区域设置为不可滚动。这些是适合内容的触发器。
最重要的是确保每个元素的所有四个边都有约束。这对于使自动尺寸标注工作至关重要。
CollapsableCell
接下来我们为那个 table 单元格原型做一个非常基本的自定义 class。将标签连接到自定义单元 class 中的出口。例如:
class CollapsableCell: UITableViewCell {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var detailLabel: UILabel!
}
从两个标签开始是最简单的。
还要确保在 Interface Builder 中将原型单元 class 设置为 CollapsableCell 并为其提供重用 ID。
CollapsableCellViewController
进入 ViewController。首先是自定义 TableViewCells 的标准内容:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "collapsableCell", for: indexPath) as! CollapsableCell
let item = data[indexPath.row]
cell.titleLabel?.text = item.title
cell.detailLabel?.text = item.detail
return cell
}
我们使用我们的自定义单元格为给定行添加了函数 return 行数和 return 单元格。希望一切都简单明了。
现在通常会有一个函数,TableView(heightForRowAt:),这是必需的,但不要添加它(如果有的话,也可以将其删除)。这就是 Auto Dimension 发挥作用的地方。将以下内容添加到 viewDidLoad:
override func viewDidLoad() {
...
// settings for dynamic resizing table cells
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 50
...
}
此时,如果您如上所述将详细信息标签设置为 0 行,并且 运行 项目,您应该会根据要放入其中的文本量获得不同大小的单元格标签。动态 TableViewCells 完成了。
可折叠单元格
要添加 collapse/expand 功能,我们可以构建我们目前正在使用的动态大小调整。将以下函数添加到 ViewController:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) as? CollapsableCell else { return }
let item = data[indexPath.row]
// update fields
cell.detailLabel.text = self.isExpanded[indexPath.row] ? item.detail1 : ""
// update table
tableView.beginUpdates()
tableView.endUpdates()
// toggle hidden status
isExpanded[indexPath.row] = !isExpanded[indexPath.row]
}
同时将 'var isExpanded = Bool' 添加到您的 ViewController 以存储行的当前展开状态(这也可以是您自定义 TableViewCell 中的 class 变量)。
构建并单击其中一行,它应该会缩小以仅显示标题标签。这就是基础。
示例项目:
github 提供了一个包含更多字段和披露人字形图像的工作示例项目。这还包括一个单独的视图,其中包含一个基于内容动态调整大小的 Stackview 演示。
一些注意事项:
- 这都是在普通的 TableViewCells 中完成的。我知道 OP 正在使用 header 个单元格,虽然我想不出为什么它不能以同样的方式工作的原因,但没有必要那样做。
- 添加和删除子视图是我最初认为最有效且最有效的方法,因为视图可以从 nib 加载,甚至可以存储以备 re-added。出于某种原因,在添加子视图后我无法调整它的大小。我想不出它不起作用的原因,但这里有一个解决方案。
在这个方法中,
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
switch indexPath.row {
case 0:
return sections[indexPath.section].collapsed! ? 0 : (100.0 + heightOfLabel2!)
case 1:
return 0
case 2:
return 0
default:
return 0
}
}
而不是使用heightOfLabel2
,尝试实现以下方法来计算每个单元格特定的高度(因为我们知道要填充的文本,它的字体和标签宽度,我们可以计算标签的高度) ,
func getHeightForBenefitDetailText2ForIndexPath(indexPath: NSIndexPath)->CGFloat
所以你的方法应该是这样的,
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
switch indexPath.row {
case 0:
return sections[indexPath.section].collapsed! ? 0 : (100.0 + getHeightForBenefitDetailText2ForIndexPath(indexPath))
case 1:
return 0
case 2:
return 0
default:
return 0
}
}
关于您第一次将几个单元格扩展的问题,请确保在重新加载 table 之前将这些单元格的 collapsed
属性 设置为 true。 =15=]
作为性能改进,您可以将为每个展开的单元格计算的高度值存储在字典中,并 return 存储字典中的值,以避免一次又一次地进行相同的计算。
希望对您有所帮助。如果没有,请分享一个示例项目以更深入地了解您的问题。
我正在使用 CollapsibleTableView from here and modified it as per my requirement to achieve collapsible sections. Here is how it looks now。
由于根据 UI 设计,我的部分有边框,因此我选择 header 部分作为我的 UI 元素,它在折叠和展开时都保存数据模式。
原因:我试过了,但无法在下面解释的这个模型中工作 -
** 在 header 节中包含我的 header 元素,并在其单元格中包含每个项目的详细信息。默认情况下,该部分处于折叠状态。当用户点击 header 时,单元格会切换显示。正如我所说,由于需要向整个部分(点击 header 及其单元格)显示一个边框,我选择 header 部分作为我的 UI 操作元素。这是我的 tableView -
代码func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections.count
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
switch indexPath.row {
case 0:
return sections[indexPath.section].collapsed! ? 0 : (100.0 + heightOfLabel2!)
case 1:
return 0
case 2:
return 0
default:
return 0
}
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = self.tableView.dequeueReusableHeaderFooterViewWithIdentifier("header") as! CollapsibleTableViewHeader
if sections.count == 0 {
self.tableView.userInteractionEnabled = false
header.cornerRadiusView.layer.borderWidth = 0.0
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
header.amountLabel.hidden = true
header.titleLabel.text = "No_Vouchers".localized()
}
else {
header.amountLabel.hidden = false
header.cornerRadiusView.layer.borderWidth = 1.0
self.tableView.userInteractionEnabled = true
header.titleLabel.text = sections[section].name
header.arrowImage.image = UIImage(named: "voucherDownArrow")
header.setCollapsed(sections[section].collapsed)
let stringRepresentation = sections[section].items.joinWithSeparator(", ")
header.benefitDetailText1.text = stringRepresentation
header.benefitDetailText2.text = sections[section].shortDesc
header.benefitDetailText3.text = sections[section].untilDate
header.section = section
header.delegate = self
if sections[section].collapsed == true {
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
}
else {
if sections[section].isNearExpiration == true {
header.benefitAlertImage.hidden = false
header.benefitAlertText.hidden = false
}
else {
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
}
}
if appLanguageDefault == "nl" {
self.totalAmountLabel.text = "€ \(sections[section].totalAvailableBudget)"
}
else {
self.totalAmountLabel.text = "\(sections[section].totalAvailableBudget) €"
}
}
return header
}
切换函数collapse/expand - 我在该部分内使用 "dynamically changing" UI 标签的高度值,然后使用这些值来扩展边框(使用其布局约束)。
func toggleSection(header: CollapsibleTableViewHeader, section: Int) {
let collapsed = !sections[section].collapsed
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
// Toggle collapse
sections[section].collapsed = collapsed
header.setCollapsed(collapsed)
// Toggle Alert Labels show and hide
if sections[section].collapsed == true {
header.cornerRadiusViewBtmConstraint.constant = 0.0
header.cornerRadiusViewTopConstraint.constant = 20.0
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
}
else {
heightOfLabel2 = header.benefitDetailText2.bounds.size.height
if sections[section].isNearExpiration == true {
header.benefitAlertImage.hidden = false
header.benefitAlertText.hidden = false
header.cornerRadiusViewBtmConstraint.constant = -100.0 - heightOfLabel2!
header.cornerRadiusViewTopConstraint.constant = 10.0
if let noOfDays = sections[section].daysUntilExpiration {
if appLanguageDefault == "nl" {
header.benefitAlertText.text = "(nog \(noOfDays) dagen geldig)"
}
else {
header.benefitAlertText.text = "(valable encore \(noOfDays) jour(s))"
}
}
}
else {
header.cornerRadiusViewBtmConstraint.constant = -80.0 - heightOfLabel2!
header.cornerRadiusViewTopConstraint.constant = 20.0
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
}
}
// Adjust the height of the rows inside the section
tableView.beginUpdates()
for i in 0 ..< sections.count {
tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: i, inSection: section)], withRowAnimation: .Automatic)
}
tableView.endUpdates()
}
问题: 根据某些条件,我需要在首次启动视图时默认展开此 table 视图中的几个 headers 部分。当我计算标签的高度并使用高度设置边框的顶部和底部约束时,很难按照设计显示扩展部分 header。
由于我的UI标签的高度默认为 21,因此内容超出了边框。
UPDATE:行高仅在滚动视图后或在 collapse/expand
之间切换时发生变化问题: 如何在第一次启动视图时计算 UI 部分 header 中显示的标签的高度? (这意味着,在我的 REST 调用完成后,将获取数据,然后我需要获取 UI 标签高度)。
目前,我正在使用heightOfLabel2 = header.benefitDetailText2.bounds.size.height
(或)
有没有更好的方法来实现这个?
提前致谢!
您可以试试这个字符串扩展来计算边界矩形
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: [NSFontAttributeName: font], context: nil)
return boundingBox.height
}
}
来源:
如果我对你的问题的理解正确,你要做的是在调用 toggleSection
.
tableHeaderView
的大小
因此,您 tableHeaderView
需要做的是调整大小
// get the headerView
let headerView = self.tableView(self.tableView, viewForHeaderInSection: someSection)
// tell the view that it needs to refresh its layout
headerView?.setNeedsDisplay()
// reload the tableView
tableView.reloadData()
/* or */
// beginUpdates, endUpdates
基本上你要做的是将上面的代码片段放在你的函数中 toggleSection(header: CollapsibleTableViewHeader, section: Int)
func toggleSection(header: CollapsibleTableViewHeader, section: Int) {
...
// I'm not sure if this `header` variable is the headerView so I'll just add my code snippet at the bottom
header.setNeedsDisplay()
/* code snippet start */
// get the headerView
let headerView = self.tableView(self.tableView, viewForHeaderInSection: someSection)
// tell the view that it needs to refresh its layout
headerView?.setNeedsDisplay()
/* code snippet end */
// reload the tableView
// Adjust the height of the rows inside the section
tableView.beginUpdates()
// You do not need this
for i in 0 ..< sections.count {
tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: i, inSection: section)], withRowAnimation: .Automatic)
}
// You do not need this
tableView.endUpdates()
}
解释:tableView 的 headerView/footerView 不会更新其布局,即使您调用 reloadData()
和 beginUpdates,endUpdates
。您需要先告诉视图它需要更新,然后再刷新 tableView
最后你还需要应用这两个代码
func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
return estimatedHeight
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableViewAutomaticDimension
}
以下是我根据对 OP 总体目标的理解所做的工作。如果我误解了,下面仍然是一个工作示例。完整的工作项目也在下面链接。
目标:
- 动态大小的 TableViewCells 也是
- 可折叠到 show/hide 其他详细信息
我尝试了多种不同的方法,这是我唯一可以开始工作的方法。
概览
设计使用了以下内容:
- 自定义 TableViewCells
- 自动布局
- TableView 自动维度
因此,如果您不熟悉这些(尤其是自动版式),可能需要先复习一下。
动态 TableViewCells
界面生成器
布置您的原型单元格。增加行高大小是最简单的。简单地从几个元素开始,以确保您可以让它正常工作。 (尽管添加到 Autolayout 中可能会很痛苦)。例如,简单地垂直堆叠两个标签,布局的整个宽度。为 "title" 制作顶部标签 1 行,为 "details"
制作第二个 0 行重要提示:要将标签和文本区域配置为增长到其内容的大小,您必须将标签设置为 0 行并将文本区域设置为不可滚动。这些是适合内容的触发器。
最重要的是确保每个元素的所有四个边都有约束。这对于使自动尺寸标注工作至关重要。
CollapsableCell
接下来我们为那个 table 单元格原型做一个非常基本的自定义 class。将标签连接到自定义单元 class 中的出口。例如:
class CollapsableCell: UITableViewCell {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var detailLabel: UILabel!
}
从两个标签开始是最简单的。
还要确保在 Interface Builder 中将原型单元 class 设置为 CollapsableCell 并为其提供重用 ID。
CollapsableCellViewController
进入 ViewController。首先是自定义 TableViewCells 的标准内容:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "collapsableCell", for: indexPath) as! CollapsableCell
let item = data[indexPath.row]
cell.titleLabel?.text = item.title
cell.detailLabel?.text = item.detail
return cell
}
我们使用我们的自定义单元格为给定行添加了函数 return 行数和 return 单元格。希望一切都简单明了。
现在通常会有一个函数,TableView(heightForRowAt:),这是必需的,但不要添加它(如果有的话,也可以将其删除)。这就是 Auto Dimension 发挥作用的地方。将以下内容添加到 viewDidLoad:
override func viewDidLoad() {
...
// settings for dynamic resizing table cells
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 50
...
}
此时,如果您如上所述将详细信息标签设置为 0 行,并且 运行 项目,您应该会根据要放入其中的文本量获得不同大小的单元格标签。动态 TableViewCells 完成了。
可折叠单元格
要添加 collapse/expand 功能,我们可以构建我们目前正在使用的动态大小调整。将以下函数添加到 ViewController:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) as? CollapsableCell else { return }
let item = data[indexPath.row]
// update fields
cell.detailLabel.text = self.isExpanded[indexPath.row] ? item.detail1 : ""
// update table
tableView.beginUpdates()
tableView.endUpdates()
// toggle hidden status
isExpanded[indexPath.row] = !isExpanded[indexPath.row]
}
同时将 'var isExpanded = Bool' 添加到您的 ViewController 以存储行的当前展开状态(这也可以是您自定义 TableViewCell 中的 class 变量)。
构建并单击其中一行,它应该会缩小以仅显示标题标签。这就是基础。
示例项目: github 提供了一个包含更多字段和披露人字形图像的工作示例项目。这还包括一个单独的视图,其中包含一个基于内容动态调整大小的 Stackview 演示。
一些注意事项:
- 这都是在普通的 TableViewCells 中完成的。我知道 OP 正在使用 header 个单元格,虽然我想不出为什么它不能以同样的方式工作的原因,但没有必要那样做。
- 添加和删除子视图是我最初认为最有效且最有效的方法,因为视图可以从 nib 加载,甚至可以存储以备 re-added。出于某种原因,在添加子视图后我无法调整它的大小。我想不出它不起作用的原因,但这里有一个解决方案。
在这个方法中,
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
switch indexPath.row {
case 0:
return sections[indexPath.section].collapsed! ? 0 : (100.0 + heightOfLabel2!)
case 1:
return 0
case 2:
return 0
default:
return 0
}
}
而不是使用heightOfLabel2
,尝试实现以下方法来计算每个单元格特定的高度(因为我们知道要填充的文本,它的字体和标签宽度,我们可以计算标签的高度) ,
func getHeightForBenefitDetailText2ForIndexPath(indexPath: NSIndexPath)->CGFloat
所以你的方法应该是这样的,
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
switch indexPath.row {
case 0:
return sections[indexPath.section].collapsed! ? 0 : (100.0 + getHeightForBenefitDetailText2ForIndexPath(indexPath))
case 1:
return 0
case 2:
return 0
default:
return 0
}
}
关于您第一次将几个单元格扩展的问题,请确保在重新加载 table 之前将这些单元格的 collapsed
属性 设置为 true。 =15=]
作为性能改进,您可以将为每个展开的单元格计算的高度值存储在字典中,并 return 存储字典中的值,以避免一次又一次地进行相同的计算。
希望对您有所帮助。如果没有,请分享一个示例项目以更深入地了解您的问题。