我正在使用 CollapsibleTableView from here并根据我的要求对其进行修改以实现可折叠部分。 Here is how it looks now .
由于根据 UI 设计,我的部分有一个边框,因此我选择了部分标题作为我的 UI 元素,它在折叠和展开模式下保存数据。
原因:我试过但无法让它在下面解释的这个模型中工作 -
** 在部分标题中包含我的标题元素,并在其单元格中包含每个项目的详细信息。默认情况下,该部分处于折叠状态。当用户点击标题时,单元格将切换为显示。正如我所说,由于需要向整个部分(点击的标题及其单元格)显示边框,因此我选择了部分标题作为我的 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
}
切换折叠/展开的功能-
我在部分内使用“动态变化”的 UILabel 的高度值,然后使用这些值来扩展边框(使用它的 layoutconstraint)。
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()
}
问题:
我需要根据某些条件在第一次启动 View 时默认扩展此表 View 中的几个部分标题。由于我正在计算标签的高度并使用高度来设置边框的顶部和底部约束,因此很难按照设计显示展开的部分标题。
由于我的 UILabel 的高度默认为 21,因此内容超出了边界。
更新 :只有在我 ScrollView 或在折叠/展开之间切换时,行高才会改变
问题:
如何在第一次启动 View 时计算部分标题中存在的 UILabel 的高度? (这意味着,在我的 REST 调用完成后,将获取数据,然后我需要获取 UIlabel 高度)。
目前,我正在使用
heightOfLabel2 = header.benefitDetailText2.bounds.size.height
(或者)
有没有更好的方法来实现这一目标?
提前致谢!
最佳答案
这是我根据对 OP 总体目标的理解所做的工作。如果我误解了,以下仍然是一个工作示例。完整的工作项目也在下面链接。
目标:
我尝试了许多不同的方法,这是我唯一可以工作的方法。
概述
设计使用以下内容:
因此,如果您不熟悉这些(尤其是 Autolayout,可能需要先回顾一下。
动态 TableViewCells
界面生成器
布置你的原型(prototype)细胞。增加行高大小是最简单的。只需从几个元素开始,以确保您可以使其正常工作。 (即使添加到 Autolayout 中可能会很痛苦)。例如,只需垂直堆叠两个标签,全宽布局。将顶部标签 1 行作为“标题”,将第二个 0 行作为“详细信息”
重要提示:要将标签和文本区域配置为增长到其内容的大小,您必须将标签设置为 0 行,将文本区域设置为不可滚动。这些是适合内容的触发器。
最重要的是确保每个元素的所有四个边都有一个约束。这对于使自动尺寸标注正常工作至关重要。
可折叠单元格
接下来,我们为该表格单元原型(prototype)制作一个非常基本的自定义类。将标签连接到自定义单元类中的导出。前任:
class CollapsableCell: UITableViewCell {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var detailLabel: UILabel!
}
简单地从两个标签开始是最简单的。
还要确保在 Interface Builder 中将原型(prototype)单元类设置为 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
}
我们添加了函数来返回行数并使用我们的自定义单元格返回给定行的单元格。希望一切都直截了当。
现在通常需要另外一个函数,TableView(heightForRowAt:),但不要添加它(或者如果你有它就取出它)。这就是 Auto Dimension 的用武之地。将以下内容添加到 viewDidLoad:
override func viewDidLoad() {
...
// settings for dynamic resizing table cells
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 50
...
}
此时,如果您如上所述将详细标签设置为 0 行并运行项目,您应该会根据您在该标签中放入的文本量获得不同大小的单元格。即 Dynamic TableViewCells 完成。
可折叠单元格
要添加折叠/展开功能,我们可以构建我们目前正在使用的动态大小。将以下函数添加到 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 中的类变量)。
构建并单击其中一行,它应该缩小以仅显示标题标签。这就是基础。
示例项目:
github 上提供了一个包含更多字段和公开人字形图像的工作示例项目.这还包括一个单独的 View ,其中包含基于内容动态调整大小的 Stackview 演示。
几点注意事项:
关于ios - Swift - tableView 行高仅在滚动或切换展开/折叠后更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44884599/