說明
TableViewCell 幾乎是必用控件,使用 TableViewCell 免不了計算其 cell 高度,網上也有非常多關於 TableViewCell 高度自適應的文章,自己也嘗試總結了計算cell高度的幾種方法。
TableViewCell 的行高計算
固定行高時
如圖所示:Cell 的格式是固定的,有一個固定高度,這種情況可以通過行高屬性 rowheight 及行高方法 heightForHeaderInSection 來設置
//設置行高的屬性
self.tableview.rowheight = 100;
//設置行高的方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 100;
}
行高不固定時
如圖所示: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);
}];
}
}