UITableVIew的高度和AutoLayout

作為一個(gè)android開發(fā)移民,在知曉UITableView可能會(huì)計(jì)算每一個(gè)cell的高度時(shí),心里面還是驚了一下。Android的開發(fā)文檔中,不會(huì)有關(guān)于計(jì)算高度這方面的內(nèi)容,數(shù)據(jù)的多少和排版決定高度數(shù)值的大小不假,但去“感知”自己的高度難道不是ui組件分內(nèi)的事兒?jiǎn)幔?/p>

可惜這種疑問并沒有支撐多久,因?yàn)榇竽X的另一側(cè)已經(jīng)出現(xiàn)android自適應(yīng)高度時(shí)各種坑和bug,比如在ScrollView當(dāng)中創(chuàng)建ListView,會(huì)發(fā)現(xiàn)設(shè)置成為自適應(yīng)高度、多行數(shù)據(jù)的ListView變成細(xì)細(xì)一杠,讓每一個(gè)新手開發(fā)大腦回旋“What the fu*k”,用手指撥動(dòng)它還會(huì)上下滑動(dòng),像極了LED。至少就動(dòng)態(tài)計(jì)算列表高度這一點(diǎn)上,ios和android都沒長(zhǎng)出什么甜果子。

好了,我只需要知道,一個(gè)展示大量列表數(shù)據(jù)的滑動(dòng)組件想知道自己的高度,就得計(jì)算各個(gè)子view的高度,即UITableView需要知道每一個(gè)UITableViewCell的高度,這樣一來,就算是每個(gè)UITableViewCell的高度大小不一,也能完美顯示。


(不同高度的cell,圖來自[www.raywenderlich.com](http://www.raywenderlich.com/87975/dynamic-table-view-cell-height-ios-8-swift))

那么如何計(jì)算每一個(gè)UITableViewCell的高度呢?很簡(jiǎn)單,分兩步:

  1. 用systemLayoutSizeFittingSize:UILayoutFittingCompressedSize獲取高度。
  2. 在heightForRowAtIndexPath當(dāng)中返回這個(gè)高度。
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        if(cell != nil) { 
           let size: CGSize = (cell?.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize))!
           return (size.height + 1)
        }
           return 0
    }

需要解釋的地方在于這個(gè)“return (size.height+1)”,為什么要加1?因?yàn)檫@里獲取的size是cell當(dāng)中contentView的size,cell作為老子肯定要比兒子高一頭啦,不然怎么管得住兒子?

Cell = ContentView(size.height) + Separator(1px)

利用systemLayoutSizeFittingSize獲取cell中contentView的size還有一個(gè)前提,就是contentView需要設(shè)定constraints,所以實(shí)際上這是一個(gè)與Auto Layout配套的高度獲取方式。


systemLayoutSizeFittingSize解釋

為每個(gè)cell計(jì)算高度再相加會(huì)得到整個(gè)UITableView的高度,問題也在于每個(gè)cell的計(jì)算過程會(huì)耗費(fèi)時(shí)間,有大量cell的時(shí)候會(huì)使得整個(gè)ui展示的效率不高,怎么辦呢?

這里有一個(gè)聰明的概念上的劃分,就是“能夠被用戶看見的cell”和“用戶還沒有看見的cell”。這里可能有上千行數(shù)據(jù),作為系統(tǒng)而言,它計(jì)算了每個(gè)cell的高度,但是手機(jī)屏幕高度有限,只看得到幾個(gè)cell,這種大量的計(jì)算不是很浪費(fèi)么?就好比我是一家生意紅火餐館,能坐200桌客人,吃飯高峰期我們家客滿了,還會(huì)在門外等50桌客人,我有必要為這等待的50桌客人備好菜么?我只需要知道等待的這50桌人大概會(huì)吃多少菜,保證廚房中的原料足夠就可以了。UITableView也有這么一個(gè)功能,給還沒有看見的cell一個(gè)估計(jì)的高度,這樣既能知道自己的高度大概是多少,又不造成浪費(fèi),提高效率。

override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return 78
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容