Apple doc说:reloadRowsAtIndexPaths:withRowAnimation
:
:
如果要提醒用户单元格的值正在更改,请调用此方法。但是,如果通知用户并不重要 - 也就是说,您只想更改单元格显示的值 - 您可以获取特定行的单元格并设置其新值。
我的问题场景是我想在按钮点击时更新单元格中的标签,并且还更新布局(即在应用的条件下添加或删除单元格的新视图)。如果在按钮上单击调用reloadRowsAtindexPath
,则tableview会随机向下滚动到tableview中的其他行。如果仅在按钮单击时更新单元格内容,则布局未正确更新。
如果有人在重装时遇到同样的问题吗?
答案 0 :(得分:2)
这比我想象的要复杂得多。
以下是我实施它的方式。我不确定这是不是一个好方法,所以拿一粒盐。找到下面项目的链接。
你需要知道两件事:
- 默认/正常单元格高度(基本上是单元格的估计高度)。
- 将视图添加到单元格后,单元格的高度增加(在我的示例中,我将高度设置为200)。
醇>
当你点击一个应该添加子视图的按钮时,你会调用一个完成处理程序,将indexPath
和heightToBeAdded
(本例中为200)作为参数传递。
完成将如下所示:
self.indexPath = iPath
self.cellHeight = self.defaultCellHeight + heightToBeAdded
UIView.beginAnimations("aaa", context: nil)
UIView.setAnimationDuration(1)
self.tableView.beginUpdates()
self.tableView.reloadRows(at: [iPath], with: .none)
self.tableView.endUpdates()
UIView.commitAnimations()
if heightToBeAdded > 0.0 {
self.addCellSubviews()
}
iPath
与您发送参数的indexPath相同。细胞高度是根据我上面描述的两件事来计算的。
当endUpdates()
调用委托时,数据源方法会遇到以下方法:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
guard let iPath = self.indexPath else { return UITableViewAutomaticDimension }
if indexPath == iPath {
return cellHeight
}
else {
return UITableViewAutomaticDimension
}
}
这会增加细胞高度。但是需要添加的实际子视图呢?
为此,我们有addCellSubviews()
,它实际上是在UITableViewCell子类内执行的完成块。仅在结束更新后调用此方法,因为此时将正确计算单元格高度。
let yView = UIView()
yView.backgroundColor = .yellow
yView.translatesAutoresizingMaskIntoConstraints = false
self.addAsSubview(sView: yView)
NSLayoutConstraint.activate([
yView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 8),
yView.topAnchor.constraint(equalTo: self.topAnchor, constant: 8),
yView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -275),
yView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -8)
])
UIView.animate(withDuration: 1, animations: {
self.layoutIfNeeded()
})
请注意有一些警告(比如轻敲一个单元格关闭另一个单元格),我相信你能够解决这个问题。
答案 1 :(得分:0)
这是估计行高的问题。将值更改为其他估计值可修复不需要的滚动问题。
苹果文档中提到:"此外,尽量使估计的行高尽可能准确。系统根据这些估计值计算滚动条高度等项目。估算越准确,用户体验就越无缝。"