[iOS] TableViewCell 自適應高度

說明

TableViewCell 幾乎是必用控件,使用 TableViewCell 免不了計算其 cell 高度,網上也有非常多關於 TableViewCell 高度自適應的文章,自己也嘗試總結了計算cell高度的幾種方法。

TableViewCell 的行高計算

固定行高時

Cell高度固定圖

如圖所示:Cell 的格式是固定的,有一個固定高度,這種情況可以通過行高屬性 rowheight 及行高方法 heightForHeaderInSection 來設置

//設置行高的屬性
self.tableview.rowheight = 100;

//設置行高的方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 100;
}

行高不固定時

Cell高度變化圖

如圖所示:UILabel 的文字長度是不固定的,有的 Cell 含有配圖,有的 Cell 不含配圖,所以 Cell 的高度不能寫死。需要根據數據的情況,讓 Cell 自適應高度。

Cell 自適應高度的方法

方法一:通過 sizeThatFits 或 boundingWithRect 計算UILabel高度 從而計算 Cell行高

對於 UIImageView 的處理:

使用masonry對圖片添加約束,當設置數據源的時候:
- 若有圖片則使用SDWebImage 設置圖片。
- 若無圖片,則不設置圖片,使用 mas_updateConstraints 更新約束將圖片高度設置爲0.

對於 UILabel 的處理:

計算UILabel高度即可:至於計算UILabel高度的計算方式,不管是普通文字的 text, 還是富文字的 attributedText 都可以通 sizeThatFits 或 boundingWithRect,計算出 UILabel的高度,詳細計算方法參考另一篇文章UILabel 設置內容的間距及高度的計算

行高的計算

由以上兩步,分別計算出 UIImageView 的高度 imaeViewHeight、UILabel 的高度labelHeigh。此時 Cell 的行高就可以通過 imageViewHeight + labelHeight 計算出行高 cellHeight, 此時將cellHeight通過模型來保存: model.cellHeigh = imageViewHeight + labelHeight ,方便以後調用 。

最後通過 heightForRowAtIndexPath 來設置該行行高

//設置行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return model.cellHeight;
}

方法二: 通過 autoLayout 設置估計高度,來自適應高度

此方法適用於 iOS8 之後版本

對於 UIImageView 的處理:

使用 masonry 對圖片添加約束,當設置數據源的時候:
- 若有圖片則使用SDWebImage 設置圖片。
- 若無圖片,則不設置圖片,使用 mas_updateConstraints 更新約束將圖片高度設置爲0.

對於 UILabel 的處理

只需要在設置數據源之後,調用 [contentLabel sizeToFit];

行高設置方法

  • 使用屬性: self.tableView.estimatedRowHeight = 100; //設置估計高度
  • 設置高度: self.tableView.rowHeight = UITableViewAutomaticDimension; //
    設置 rowHeight 默認值

這樣 Cell 就可以自適應高度了。
此時,會自適應高度,所以 heightForRowAtIndexPath 方法設置高度就沒有效果。
- (CGFloat)tableView:(UITableView )tableView heightForRowAtIndexPath:(NSIndexPath )indexPath { } 失效。

方法三: 使用第三方框架 UITableView+FDTemplateLayoutCell

使用UITableView+FDTemplateLayoutCell,就算比較複雜的界面,只需要調用 fd_heightForCellWithIdentifier 即可輕鬆解決。
此框架使用方法非常簡單,
1. 首先檢查:Cell 中 Y 方向約束設置完整。
3. 然後檢查:是否註冊 cell, registerClass。
4. 導入頭文件:UITableView+FDTemplateLayoutCell.h。
5. 在-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ }方法中調用 API。

API 設置方法如下:

#import <UITableView+FDTemplateLayoutCell.h>
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [tableView fd_heightForCellWithIdentifier:@"identifer" cacheByIndexPath:indexPath configuration:^(id cell) {
        // 配置 cell 的數據源,和 "cellForRow" 乾的事一致,比如:        
        [cell configureCellWithData:self.model[indexPath.row]];
    }];
}

在設置數據時,若圖片爲空,則不需要設置圖片,及清零圖片高度:

- (void)configureCellWithData:(JHmodel *)model {
//設置數據
  _contentLabel.text = [NSString stringWithFormat: @"%@:%@\n\n%@:%@",
                        self.title,
                        model.newsTitle,
                        self.news,
                        model.newcontent,
                        ];
//當圖片不爲空時,設置圖片,更新約束
    if (model.urlImage != nil) {
    [self.urlImageView sd_setImageWithURL:[NSURL URLWithString:model.urlImage]];
    [self.urlImageView mas_updateConstraints:^(MASConstraintMaker *make) {
      make.height.mas_equalTo(180);
      make.bottom.mas_equalTo(self.contentView).offset(-15);
    }];
  } else {
//當圖片爲空時,不設置圖片,更新約束
    [self.urlImageView mas_updateConstraints:^(MASConstraintMaker *make) {
      make.height.mas_equalTo(0);
      make.bottom.mas_equalTo(self.contentView).offset(0);
    }];
  }
}

ViewDemo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章