2015-09-26 48 views
0

如果我把一個自定義視圖放在一個單元格中,如果我的自定義視圖的高度發生了變化,如何通知tableview更新單元格的高度?我試過invalidateIntrinsicContentSize,但不起作用。 ReloadData的作品,但我懷疑是否使用如何更新自行調整tableview的高度?

self.superview?.superview?.superview as! UITableView).reloadData() 

是一個很好的實施。 我已經看到類似的問題here但這都是關於從標準庫中查看的。而thisthis沒有答案。

回答

1

您正在朝着正確的方向思考。但是,您的方法存在兩個問題:

  1. reloadData重新加載整個表視圖,並且不會動畫更改。
  2. 當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?() 
} 
+0

我想到了這一次。但是,如果我們之前刪除單元格,indexPath可以改變,所以我會直接調用tableview的beginUpdate和endUpdate(在我的情況下)(只有五個單元格)。我相信調用invalidateIntrinsicContentSize應該更新單元格的高度,以便自定義表格,所以這是一個蘋果應該修復的錯誤。 –

+0

噢,是的,你是完全正確的,當閉包被執行時(考慮到刪除和新的單元格),應該檢索'indexPath'。我編輯了我的答案。我同意蘋果應該在這裏找到一個可靠的解決方案。 – joern