前幾天給大家介紹了一個(gè)自適應(yīng)cell高度的第三方開源擴(kuò)展,今天我們試著不依靠第三方框架在使用Autolayout的基礎(chǔ)上進(jìn)行cell高度的自適應(yīng).
在進(jìn)入正題之前,讓我們先認(rèn)識(shí)一個(gè)方法
tableView: estimatedHeightForRowAtIndexPath:
這是7.0出現(xiàn)的UITableViewDelegate中的方法,表示返回某行cell的預(yù)估高度.
那么這個(gè)預(yù)估高度有什么作用呢?
我想在大家初次解決tableViewCell高度自適應(yīng)問題的時(shí)候應(yīng)該會(huì)這樣想過:在繪制cell的時(shí)候我們可以得到cell準(zhǔn)確的高度,如果拿到這個(gè)高度設(shè)置成cell的高度不是剛剛好嗎? 悲劇的是tableView顯示數(shù)據(jù)的時(shí)候會(huì)先調(diào)用高度的協(xié)議方法(heightForRow...),然后才進(jìn)行繪制(調(diào)用cellForRow...),也就是說,調(diào)用高度的時(shí)候cell可能都還不存在呢!
tableView: estimatedHeightForRowAtIndexPath:就是為了改變這個(gè)問題誕生的.我們用數(shù)據(jù)說話:當(dāng)我們沒有調(diào)用estimatedHeightForRow...這個(gè)方法的時(shí)候,tableView調(diào)用幾個(gè)代理方法的順序是這樣的:(測試數(shù)據(jù)為5行)
可以看出,控制器在得知cell的行數(shù)n之后,會(huì)先一口氣調(diào)用n次heightForRow方法,這是為了方便tableView計(jì)算自己的contentSize,進(jìn)一步計(jì)算指示條的大小和位置.
在添加了estimatedHeightForRow...方法后,調(diào)用順序變成了:
也就是說,愿望實(shí)現(xiàn)了. 這個(gè)方法的出現(xiàn)使得tableView代理方法的調(diào)用順序發(fā)生了改變,從而達(dá)到了前面說的"繪制cell時(shí)得到準(zhǔn)確高度,然后把高度再拿給tableView去顯示"的目的.并且,這個(gè)方法避免了一開始調(diào)用n次heightForRow的方法導(dǎo)致的一些不必要的計(jì)算.
現(xiàn)在讓我們整理一下tableView在這段時(shí)間是怎么工作的:
- 首先tableView會(huì)先向代理拿得到每個(gè)cell的預(yù)估高度(estimatedHeightForRow...方法),并且拿這個(gè)高度去計(jì)算整個(gè)tableView應(yīng)該顯示的范圍
- 根據(jù)每行預(yù)估的高度,算出一屏顯示的cell的個(gè)數(shù),并先對(duì)這些cell(調(diào)用cellForRow...方法)進(jìn)行繪制
- 在繪制時(shí)拿到cell的真實(shí)高度,然后放在heightForRow...方法里面拿給tabelView去用
- 屏幕滾動(dòng)(有cell進(jìn)入屏幕)的時(shí)候,仍然會(huì)調(diào)用繪制以及獲取真實(shí)高度的方法.
簡單點(diǎn)說,就是預(yù)估高度用來讓tableView心里有個(gè)底,把cell先繪制出來,但最后實(shí)際的cell高度還是會(huì)從heightForRow...方法中獲取.