iOS-談談UITableView中estimatedRowHeight到底該不該禁用

ofollow,noindex">目錄
- 官方文件
- 視覺方面
- 程式碼方面
- 想說什麼
- 結論、到底該不該禁用呢
官方文件
關於 estimatedRowHeight/estimatedSectionHeaderHeight /estimatedSectionFooterHeight
官方文件中都有這樣一段說明:
Providing a nonnegative estimate of the height of rows can improve the performance of loading the table view. If the table contains variable height rows, it might be expensive to calculate all their heights when the table loads. Using estimation allows you to defer some of the cost of geometry calculation from load time to scrolling time.
大意是啟用這個屬性可以提升效能。
因為他把一些計算成本從載入時延遲到滾動時。
具體是什麼計算?答案是 contentSize
屬性、開啟預估之後TableView會在滾動時獲取cell實際的高度、並且修改 contentSize
值。
這個影響主要在兩方面:視覺方面、程式碼方面。
視覺方面
滑動時右側滑動條、會有一些長短變化以及些許抖動。
這個很容易理解。畢竟總rect發生了變化、滑動條自然需要發生變化。
程式碼方面
這才是我們關心的重點
1. 禁用預估功能
tableView會每次都讀取所有 indexPath
的 heightForRowAtIndexPath
進行行高計算。
這就是文件中影響應能的主要原因所在(
)
2. 開啟預估功能
TableView
的 contentSize
值以及 rectForSection
方法返回的 rect
也為預估值。只有當你劃過所有的cell、才會得到真實的值。
但是如果你的cell高度與預估的差太多、在 contentoffset
偏移很大的情況下直接 reload
會出現cell展示偏移的情況。(
)
如果cell差別過大。你也可以使用 tableView:estimatedHeightForRowAtIndexPath:
來單獨設定、或者 insertRowsAtIndexPaths
這種方式來新增新的cell。但是後者實在麻煩。
想說什麼
iOS11之前是為0、在iOS11下、這個值預設為44。
程式碼裡建立TableView的時候經常copy程式碼、由於某些SDK的原因、經常出現以下程式碼:
if (@available(iOS 11.0, *)) { tableView.estimatedRowHeight = 0; tableView.estimatedSectionFooterHeight = 0; tableView.estimatedSectionHeaderHeight = 0; }
而這、恰恰會會影響到效能。
至於剛才所說的需要我們這樣設定的SDK、按網上來看目前是以 MJRefresh
為主。 但好在現在已經修復了這個bug 。
結論、到底該不該禁用呢
1. 如果你可以很好的控制cell高度
啟用吧、對效能有好處。起碼會剩下幾十次計算
2. 如果你沒辦法很好的控制cell高度(比如有展開啊什麼亂七八糟的)
禁了吧、否則載入更多的時候直接 reload
有可能會出問題。
如果你非要啟用、最好自己按照閥值測試效果再決定。
然後安利一下相關的東西 《iOS-談一談自適應Cell的高度快取》 沒準對你有幫助呢
最後
本文主要是自己的學習與總結。如果文記憶體在紕漏、萬望留言斧正。如果願意補充以及不吝賜教小弟會更加感激。