iOS中tableview是一個經(jīng)常用的控件夹抗,尤其它的cell高度計算令人頭疼∽菔考慮到tableview的性能優(yōu)化漠烧,我們一般都會在model封裝時提前計算好cell的高度杏愤,代理返回cell高度時,拿到model已脓,直接給它已計算好的高度珊楼。iOS8.0之后,可以使用AutoLayout結(jié)合tableview的屬性讓cell自己計算出高度度液。
使用步驟
- cell中使用Autolayout布局厕宗,例如這樣:
cell高度=約束1的值+label1的高度+約束2的值+label2的高度+約束3的值
文字內(nèi)容動態(tài)變化,那么label高度會動態(tài)變化恨诱,最終cell高度也會動態(tài)變化。 - 顯設(shè)置tableview的屬性:
//給tableview設(shè)置一個默認高度
self.tableView.estimatedRowHeight = 45;
//告訴tableview骗炉,cell是自適應(yīng)的
self.tableView.rowHeight = UITableViewAutomaticDimension;
常遇問題
-
label的lines設(shè)置為1照宝,label不能換行,高度始終是一行的高度句葵,應(yīng)該酌情設(shè)置厕鹃,一般設(shè)置0即可,不限行高乍丈。
-
contentview的高度沒有被子視圖約束填充滿剂碴。
-
label的寬度因為缺少約束而沒法確定。
-
約束報錯轻专,列如:
因為bottom的約束值與實際的值不符忆矛,可以改變約束值,或者改變cell的高度
-
使用storyboard繪制的cell请垛,Controller中注冊了cell子類催训,導(dǎo)致繪制的cell顯示不出來。
不需這樣
// [self.tableView registerClass:NSClassFromString(@"MyTableViewCell1") forCellReuseIdentifier:cellId1];
// [self.tableView registerClass:NSClassFromString(@"MyTableViewCell2") forCellReuseIdentifier:cellId2];
直接這樣即可
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row<self.data1.count) {
MyTableViewCell1 *cell = [tableView dequeueReusableCellWithIdentifier:cellId1 forIndexPath:indexPath];
cell.model=self.data1[indexPath.row];
return cell;
}else
{
MyTableViewCell2 *cell = [tableView dequeueReusableCellWithIdentifier:cellId2 forIndexPath:indexPath];
cell.model=self.data2[indexPath.row-self.data1.count];
return cell;
}
}
- cell的高度顯示不正確宗收,需要刷新下tableview漫拭,才會顯示正確。那是因為cell中l(wèi)abel的賦值是在layoutSubviews完成的混稽。
-(void)layoutSubviews
{
[super layoutSubviews];
self.lbl.text=self.model.contentStr;
}
要么:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row<self.data1.count) {
MyTableViewCell1 *cell = [tableView dequeueReusableCellWithIdentifier:cellId1 forIndexPath:indexPath];
MyModel1 *model=self.data1[indexPath.row];
cell.lbl1.text=model.str1;
cell.lbl2.text=model.str2;
// cell.model=self.data1[indexPath.row];
return cell;
}else
{
MyTableViewCell2 *cell = [tableView dequeueReusableCellWithIdentifier:cellId2 forIndexPath:indexPath];
MyModel2 *model=self.data2[indexPath.row];
cell.lbl.text=model.contentStr;
// cell.model=self.data2[indexPath.row-self.data1.count];
return cell;
}
}
很多情況下我們還是希望賦值操作是在cell類中完成時采驻,也可以這樣:
- (void)showData
{
self.lbl1.text=self.model.str1;
self.lbl2.text=self.model.str2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row<self.data1.count) {
MyTableViewCell1 *cell = [tableView dequeueReusableCellWithIdentifier:cellId1 forIndexPath:indexPath];
cell.model=self.data1[indexPath.row];
[cell showData];
return cell;
}else
{
MyTableViewCell2 *cell = [tableView dequeueReusableCellWithIdentifier:cellId2 forIndexPath:indexPath];
cell.model=self.data2[indexPath.row-self.data1.count];
[cell showData];
return cell;
}
}
進階
假若label在contentview的多級子視圖中也是可以實現(xiàn)cell高度自適應(yīng)的。
原理也是同樣的
demo效果
demo在這里