前言:前一文自適應TableViewCell(純代碼)介紹了如何使用純代碼方式實現
tableViewCell
自適應高度,那么本文就來介紹一下如何使用XIB+Autolayout
的方式實現tableViewCell
的自適應高度.先看一下效果圖,和上篇文章介紹的效果圖是一樣的.
圖1.gif
- 1 . 創建
model
類,添加數據源,并且保存在數組中.這個數據源我是寫在了,plist
文件當中,并且使用cocoaPods
導入MJExtension
進行數據轉模型.
#pragma mark - 懶加載
- (NSArray *)dataSource {
if (!_dataSource) {
self.dataSource = [AdaptiveModel mj_objectArrayWithFilename:@"ModelList.plist"];
}
return _dataSource;
}
- 2 . 創建自定義的
AdaptiveTableViewCell
繼承自UITableViewCell
創建的時候勾選XIB
, 接下來在XIB中添加子控件,并且給子控件添加約束.設置nameLabel
的左邊距和上邊距是10,text_label
距離nameLabel
的上邊距是10,距離contentView
的左右邊距都是10. 設置prctureImageView
距text_Label
的上邊距是10,距contentView
的左邊距和下邊距是10,并且設置寬高都是100;
圖2.png
需要注意: 要設置text_Label
的lines
是0,否則不會自動換行.
圖3.png
- 3 . 接下來要在
viewController
中注冊自定義單元格,這個時候有2個地方需要注意,一是需要設置tableView
的rowHeight
為UITableViewAutomaticDimension
, 這行代碼的租用是設置tableView
所有的cell
是根據真實高度自動計算的(根據設置的約束), 另外就是需要設置tableView
的預算高度.這兩者缺一不可.這兩行代碼放在一起是就是使用了self-sizing
技術,這個技術也是在iOS8
以后才支持的.目前已經iOS10.1
了,大可不必擔心.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.tableView = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain];
// [self.tableView registerClass:[AdaptiveTableViewCell class] forCellReuseIdentifier:identifier];
[self.tableView registerNib:[UINib nibWithNibName:@"AdaptiveTableViewCell" bundle:nil] forCellReuseIdentifier:@"AdaptiveCell"];
// self-sizing(iOS8以后才支持)
// 設置tableView所有的cell的真實高度是自動計算的(根據設置的約束)
self.tableView.rowHeight = UITableViewAutomaticDimension;
// 設置tableView的估算高度
self.tableView.estimatedRowHeight = 200;
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self.view addSubview:self.tableView];
}
需要注意:tableView
的估算高度,可以給一個隨意的值,只要是大于0的就可以.建議給這個值給的稍微大一點,這里面牽扯到tableView
性能優化的一些東西.
- 4 .配置單元格,給單元格上的控件賦值.
// 設置單元格
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
AdaptiveTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AdaptiveCell" forIndexPath:indexPath];
// 傳遞數組模型
cell.model = self.dataSource[indexPath.row];
return cell;
}
- 5 . 到這一步我們就要思考一下,我們剛開始設置單元格上的控件的時候,圖片給的是一個固定的高度100,但是有些數據中沒有圖片,那我們就可以把圖片的高度設置成0,把圖片距離下邊框的間距也設置成0.否則,沒有圖片的那些單元格中,就會出現一片空白的區域.我們需要把圖片的高度約束和下邊距約束拉成屬性,在
model
的setter
方法中進行修改.
圖4.png
@interface AdaptiveTableViewCell ()
@property (weak, nonatomic) IBOutlet UILabel *nameLabel; // 姓名
@property (weak, nonatomic) IBOutlet UILabel *text_Label; // 正文
@property (weak, nonatomic) IBOutlet UIImageView *picthreView; // 圖片
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *pictureHeight; // 圖片高度約束
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *pictureBottom; // 圖片底部約束
@end
// 重寫setter方法
- (void)setModel:(AdaptiveModel *)model {
if (_model != model) {
_model = model;
}
self.nameLabel.text = model.name;
self.text_Label.text = model.text;
if (model.picture) { // 有圖片
self.picthreView.hidden = NO;
self.picthreView.image = [UIImage imageNamed:model.picture];
self.pictureHeight.constant = 100;
self.pictureBottom.constant = 10;
} else { // 沒有圖片
self.picthreView.hidden = YES;
self.pictureHeight.constant = 0;
self.pictureBottom.constant = 0;
}
}
需要注意:在沒有圖片時候需要把圖片的約束更改為0,在有圖片的時候也一定要把約束更改回來,否則因為tableViewCell
的循環引用,界面滑動的時候,會造成顯示混亂.
總結:到這里我們就把自適應
TableViewCell
的功能實現了.對比來說,使用AutoLayout
方式要比使用純代碼的方式更加簡單一些.不需要再去計算控件的高度這些繁瑣的步驟,只有幾個注意事項需要多注意.避免不必要的錯誤.
- 1.要設置
text_Label
的line
是0,否則不會自動換行. - 2.要設置
tableView
所有的cell
的真實高度是自動計算的(根據設置的約束)self.tableView.rowHeight = UITableViewAutomaticDimension;
// 設置tableView
的估算高度self.tableView.estimatedRowHeight = 200;
- 3.在沒有圖片時候需要把圖片的約束更改為0,在有圖片的時候也一定要把約束更改回來,否則因為
tableViewCell
的循環引用,界面滑動的時候,會造成顯示混亂.
另附本文gitHub地址