Swift - tableView行高只有在滚动或切换展开/折叠后才会更新。
Swift - tableView行高只有在滚动或切换展开/折叠后才会更新。
我正在使用这里的CollapsibleTableView,并根据我的要求对其进行修改,以实现可折叠的部分。这是它的样子。
由于根据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的高度值,然后使用这些值来扩展边框(使用其布局约束)。
func toggleSection(header: CollapsibleTableViewHeader, section: Int) {
let collapsed = !sections[section].collapsed
header.benefitAlertImage.hidden = true
header.benefitAlertText.hidden = true
// 切换折叠
sections[section].collapsed = collapsed
header.setCollapsed(collapsed)
// 切换警告标签的显示和隐藏
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
}
}
// 调整部分内的行高
tableView.beginUpdates()
for i in 0 ..< sections.count {
tableView.reloadRowsAtIndexPaths([NSIndexPath(forRow: i, inSection: section)], withRowAnimation: .Automatic)
}
tableView.endUpdates()
}
问题:
我需要在视图第一次启动时,默认展开表视图中的某些部分头部,根据一些条件。由于我在计算标签的高度并使用高度设置边框的顶部和底部约束时,根据设计显示展开的部分头部变得困难。
内容超出边框,因为我的UILabel的高度默认为21。
更新:只有在我浏览视图或在折叠/展开之间切换时,行高才会改变
问题:
如何在视图首次启动时计算部分头部中UILabel的高度?(也就是说,在我的REST调用完成后,获取数据,然后需要获取UIlabel高度)。
目前,我正在使用heightOfLabel2 = header.benefitDetailText2.bounds.size.height
(或者)
有更好的方法实现这个吗?
提前致谢!
问题的原因是在tableView的heightForRowAtIndexPath方法中,使用了一个变量heightOfLabel2来计算某些行的高度。然而,该变量的值在计算高度之前并没有被初始化,导致计算出的高度不正确。
解决方法是实现一个新的方法getHeightForBenefitDetailText2ForIndexPath,用于计算每个行的高度。在该方法中,根据文本内容、字体和标签宽度等信息来计算标签的高度。然后在tableView的heightForRowAtIndexPath方法中,调用该方法来获取每个行的正确高度。
此外,如果想要展开某些行,需要在重新加载表格数据之前将这些行的collapsed属性设置为true,以确保它们被正确展开。
为了提高性能,可以将每个展开行计算出的高度值存储在一个字典中,并在需要时从字典中获取值,避免重复计算。
希望这些方法能帮助你解决问题。如果还有问题,请提供一个示例项目以便更好地了解你的问题。
问题出现的原因是tableView的headerView在调用toggleSection方法时无法自动更新布局。解决方法是在toggleSection方法中添加代码来刷新headerView并重新加载tableView,同时还需要在tableView的代理方法中设置headerView的高度。
具体解决方法如下:
在toggleSection方法中添加以下代码:
// 获取headerView
let headerView = self.tableView(self.tableView, viewForHeaderInSection: someSection)
// 告诉headerView需要刷新布局
headerView?.setNeedsDisplay()
// 重新加载tableView
tableView.reloadData()
// 或者
// beginUpdates, endUpdates
将以上代码放在toggleSection方法的底部。
在tableView的代理方法中添加以下代码:
func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
return estimatedHeight
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return UITableViewAutomaticDimension
}
通过正确使用NSLayoutConstraints来设置headerView的约束,可以使headerView自动扩展。如果想要tableViewCell也能扩展,需要对代码进行修正。
以上是解决问题的方法。
问题出现的原因:在Swift中,tableView的行高度更新只有在滚动或切换展开/折叠时才生效。
解决方法:
1. 在Interface Builder中创建一个原型单元格,并将其行高调整为所需大小。
2. 创建一个自定义的TableViewCell类,并将标签连接到该类中的outlets。
3. 在ViewController中实现tableView的数据源方法,返回自定义的TableViewCell,并设置标签的文本。
4. 在viewDidLoad方法中,设置tableView的rowHeight属性为UITableViewAutomaticDimension,estimatedRowHeight属性为一个预估的行高。
5. 在tableView的didSelectRowAt方法中,更新所选行的展开/折叠状态,并调用tableView的beginUpdates和endUpdates方法刷新tableView的布局。
以上就是解决Swift中tableView行高度更新问题的原因和解决方法。通过这些步骤,我们可以实现动态调整行高并展开/折叠的TableView。