作為一個(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都沒長出什么甜果子喧务。
好了,我只需要知道甩苛,一個(gè)展示大量列表數(shù)據(jù)的滑動(dòng)組件想知道自己的高度蹂楣,就得計(jì)算各個(gè)子view的高度,即UITableView需要知道每一個(gè)UITableViewCell的高度讯蒲,這樣一來痊土,就算是每個(gè)UITableViewCell的高度大小不一,也能完美顯示墨林。
那么如何計(jì)算每一個(gè)UITableViewCell的高度呢?很簡(jiǎn)單旭等,分兩步:
- 用systemLayoutSizeFittingSize:UILayoutFittingCompressedSize獲取高度酌呆。
- 在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配套的高度獲取方式娜饵。
為每個(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
}