您正在朝着正确的方向思考。但是,您的方法存在两个问题:
reloadData
重新加载整个表视图,并且不会动画更改。
- 当Apple更改
UITableView
视图层次结构时,向上移动超视图链必然会中断。他们之前已经这样做了,所以他们可能会再次这样做。
要解决第一个问题,您应该改为拨打reloadRowsAtIndexPaths:withRowAnimation:
。这只会重新载入您在indexPath数组中指定的单元格。所以你传递一个只包含你的单元格的indexPath的数组。
第二个问题有点棘手,因为UITableViewCell
没有提及其UITableView
(它不应该)。所以它不能直接告诉UITableView
重新加载单元格。
您可以给每个单元格一个闭包,它应该在高度发生变化时执行闭包。所以,你只需要添加在你的自定义单元格的封闭特性:
class YourCustomTableViewCell: UITableViewCell {
var resizeClosure: (() -> Void)?
...
而当你出列的单元格设置这个封闭在UITableViewControllerDataSource
:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("YourCustomCellIdentifier", forIndexPath: indexPath)
if let customCell = cell as? YourCustomTableViewCell {
customCell.resizeClosure = { [weak cell, weak tableView] in
if let currentIndexPath = tableView?.indexPathForCell(cell!) {
tableView?.reloadRowsAtIndexPaths([currentIndexPath], withRowAnimation: .Automatic)
}
}
}
return cell
}
只要确保你添加tableView
到封闭的捕获列表以避免强烈的参考周期。这是通过将[weak tableView]
添加到闭包完成的。
,然后在细胞改变其高度你只是执行关闭和细胞将重新加载:
func someFunctionThatChangesTheHeight() {
// change the height
resizeClosure?()
}
我想到了这一次。但是,如果我们之前删除单元格,indexPath可以改变,所以我会直接调用tableview的beginUpdate和endUpdate(在我的情况下)(只有五个单元格)。我相信调用invalidateIntrinsicContentSize应该更新单元格的高度,以便自定义表格,所以这是一个苹果应该修复的错误。 –
噢,是的,你是完全正确的,当闭包被执行时(考虑到删除和新的单元格),应该检索'indexPath'。我编辑了我的答案。我同意苹果应该在这里找到一个可靠的解决方案。 – joern