AutoLayout自適應(yīng)Cell高度

iOS中tableview是一個(gè)經(jīng)常用的控件,尤其它的cell高度計(jì)算令人頭疼。考慮到tableview的性能優(yōu)化,我們一般都會在model封裝時(shí)提前計(jì)算好cell的高度,代理返回cell高度時(shí),拿到model,直接給它已計(jì)算好的高度。iOS8.0之后,可以使用AutoLayout結(jié)合tableview的屬性讓cell自己計(jì)算出高度。

使用步驟

  • cell中使用Autolayout布局,例如這樣:
    Cell的AutoLayout樣式.png

    cell高度=約束1的值+label1的高度+約束2的值+label2的高度+約束3的值
    文字內(nèi)容動態(tài)變化,那么label高度會動態(tài)變化,最終cell高度也會動態(tài)變化。
  • 顯設(shè)置tableview的屬性:
//給tableview設(shè)置一個(gè)默認(rèn)高度
self.tableView.estimatedRowHeight = 45;
//告訴tableview,cell是自適應(yīng)的
self.tableView.rowHeight = UITableViewAutomaticDimension;

常遇問題

  • label的lines設(shè)置為1,label不能換行,高度始終是一行的高度,應(yīng)該酌情設(shè)置,一般設(shè)置0即可,不限行高。


    image.png
  • contentview的高度沒有被子視圖約束填充滿。


    image.png
  • label的寬度因?yàn)槿鄙偌s束而沒法確定。


    image.png
  • 約束報(bào)錯(cuò),列如:


    cell的約束錯(cuò)誤.png

    因?yàn)閎ottom的約束值與實(shí)際的值不符,可以改變約束值,或者改變cell的高度

  • 使用storyboard繪制的cell,Controller中注冊了cell子類,導(dǎo)致繪制的cell顯示不出來。


    cell樣式.png

不需這樣

//    [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,才會顯示正確。那是因?yàn)閏ell中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類中完成時(shí),也可以這樣:

- (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;
    }
}

進(jìn)階

假若label在contentview的多級子視圖中也是可以實(shí)現(xiàn)cell高度自適應(yīng)的。


image.png

原理也是同樣的

demo效果

image.png
image.png

demo在這里

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容