iOS 8 中通過UITableViewAutomaticDimension 常量支持自適應高度的單元格(iOS 7 就要麻煩得多)。但是在實際應用中,我們需要注意以下幾個問題:
1、 設置好模板單元格的自動布局
模板單元格中,subviews的自動局部必須要能夠把單元格撐滿。也就是說,iOS 必須能夠通過內容的自動布局約束計算出 cell 的高。以下面的單元格為例:
cell中有上下兩個 Label,上面的Label只有一行文本(lines為1),所以高度在運行時不會改變,但下面的Label是多行文本(lines為0),運行時其高度會根據文本內容自動增長。
左圖中的自動布局是正確的,因此運行時單元格能夠自適應高度。這是因為iOS能夠根據cell的contentView中的各個子View計算出cell的正常高度,計算方式為:
cell 高度 = 第1個Label的top+第1個Label高度+第2個Label的top+第2個Label高度(根據內容自動計算)+第2個Label的bottom
但是當我們將第2個Label的top約束(或者bottom約束)刪除,如右圖所示,我們已經把圖中紅框所示位置的約束刪除了,則iOS無法計算單元格的高度了。因為上述公式中的一個變量缺失。這樣運行時表格中的所有cell都是固定高度,cell之間會發生重疊,同時控制台會報錯:
Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell’s content view. We’re considering the collapse unintentional and using standard height instead.
2、 在viewDidLoad中設置tableView
接下來在viewDidLoad中設置tableView:
tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 100;
第一句的作用如前面所述,是開啟iOS 8的單元格的自適應高度特性。第二句代碼也是同樣的功能,estimatedRowHeight讓你提供一個預先估計cell的高度值,這個值根本可以亂設(只要不為0),但如果你不寫這句,或者將estimatedRowHeight屬性設置為0,則iOS 8的單元格自動高度特性也不會生效。
3、 heightForRowAtIndexPath方法和estimatedHeightForRowAtIndexPath方法
開啟了iOS 8 的單元格自動高度特性後,這兩個方法就不需要了,或者簡單地返回一個UITableViewAutomaticDimension常量:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
當然,完全刪除這兩個方法也沒有關系。