您正在朝着正確的方向思考。但是,您的方法存在兩個問題:
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