当UITableViewCell被点击时,UILabel未按预期更新的行数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当UITableViewCell被点击时,UILabel未按预期更新的行数相关的知识,希望对你有一定的参考价值。
当点击单元格时,我正在更改自定义UITableViewCell标签上的numberOfLines
属性。但是,直到第二次点击时才会在UI中反映出来。单元格在表格视图中配置为原型单元格,最初有2行。
有趣的是,当我在numberOfLines
函数运行之前和之后打印出tapped()
值时,值开始不同,然后同步 - 在第一次点击后,我看到函数运行前的2行,然后是函数运行后的0行。然而,在后续的点击之后,我在我的函数之前和之后看到了相同的值,这使得它似乎没有做任何事情,即使UI确实拉伸和缩小单元格,并且numberOfLines
值在下次更改时会更改didSelectRowAtIndexPath
功能运行。
我只是用tableView.reloadRows()
看到这种行为。如果我使用tableView.reloadData()
进行全面更新,则第一次点击时,单元格会适当地增长并折叠。然而,这感觉有点火腿,并没有像reloadRows()
那样很好地制作动画。
TableView实现
func tableView(_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) as? ReviewTableViewCell
else { return }
let data = tableData[indexPath.row]
print("old number of lines: (cell.detailLabel.numberOfLines)")
//data.isOpen is set to false initially
cell.tapped(data.isOpen)
tableData[indexPath.row].isOpen = !data.isOpen
tableView.reloadRows(at: [indexPath], with: .fade)
print("old number of lines: (cell.detailLabel.numberOfLines)")
// tableView.reloadData()
}
自定义表视图单元格方法
func tapped(_ isOpen: Bool) {
if !isOpen {
detailLabel.numberOfLines = 0 }
else {
detailLabel.numberOfLines = 2 }
}
我希望这个代码在tableView.reloadRows()
重新加载时扩展单元格,如果numberOfLines
设置为0,当它设置为2时折叠单元格。这确实有效,但只有在单击两次+单元格之后。这也适用于第一次点击。
这是一个显示问题的gif链接:https://imgur.com/a/qe2uAXj
这是一个示例项目,类似于我的应用程序中发生的事情:https://github.com/imattice/CellLabelExample
为了清楚起见,要获得这个技巧工作,UILabel
一般必须限制在它的超视图的每一边,这样当它改变它的intrinsicContentSize
能够推动每一方以容纳文本。
说,尝试使用这两种方法包装tapped方法:
tableView.beginUpdates()
if !isOpen {
detailLabel.numberOfLines = 0
}
else {
detailLabel.numberOfLines = 2
}
tableView.endUpdates()
当然tableview必须设置为自动大小:
tableView.estimatedRowHeight = <#What you want#>
tableView.rowHeight = UITableView.automaticDimension
我能够弄清楚发生了什么。问题分为两部分。
第一部分是调用reloadRows()
。此方法使用新单元格交换单元格,而不是更新已存在的单元格。因此,我正在更改隐藏交换单元格上的行数而不是视图中的单元格。 the docs中提到了这种行为:
重新加载行会导致表视图向其数据源询问该行的新单元格。该表动画化了新单元格,因为它为旧行设置了动画。
另外,我使用结构作为跟踪单元打开状态的数据模型。在Swift中,结构是写时复制,这意味着如果在该结构上更改了值,则会创建一个新结构,而不是更改我指向的结构的值。这意味着行tableData[indexPath.row].isOpen = !data.isOpen
没有做任何有用的事情 - 我们查看索引路径中的tableData结构,获取它的isOpen
值,复制一个新结构并更改新结构的isOpen
值,然后将其抛出,因为新结构是未分配到任何地方
解决方案是不使用reloadRows()
方法并使用A)class
作为数据对象B)将indexPath.row中的数据替换为复制的struct
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) as? CustomCell else { return }
var data = tableData[indexPath.row]
tableView.beginUpdates()
cell.tapped(isOpen: data.isOpen)
data.isOpen = !data.isOpen
tableData[indexPath.row] = data
tableView.endUpdates()
}
以上是关于当UITableViewCell被点击时,UILabel未按预期更新的行数的主要内容,如果未能解决你的问题,请参考以下文章
当单元格具有动态宽度时,CollectionView 中的间距不正确?
当我点击 UITableViewCell 时,视图控制器没有被推送。