iOS中TableViewCell的自动行高设置
2016-10-23 本文已影响368人
闻人歌
本次介绍2种经常用到自动调整行高的cell.一种是向UILabel中写入内容,内容大小不固定.因此其中label的size也不确定.另一种,就是其中的某个控件高度在不断变化,因此要不断计算这个控件的高度.
演示效果:
主要工具:Masonry框架
第一种:label内容动态设置
由于文字的数量是不定的,label因此高度是可变的,导致cell的高度可变.因此要使用tableViewCell自动设置行高.
首先,要使用tableViewCell自动设置行高必然要为tableView设置2个属性,即:
table.rowHeight = UITableViewAutomaticDimension;
table.estimatedRowHeight = 100;
文字不定,所以显示内容的label的约束先不做高度约束.定义一个MASConstraint 属性来记录高度
@interface LabelCell (){
MASConstraint *heightCons;
}
@property (nonatomic, weak)UILabel *redLabel;
@property (nonatomic, weak)UILabel *blueLable;
@end
[blueLabel makeConstraints:^(MASConstraintMaker *make) {
make.leading.equalTo(self.contentView).offset(SideMargin);
make.trailing.equalTo(self.contentView).offset(-SideMargin);
make.top.equalTo(redLabel.bottom).offset(10);
}];
// 设置contentView的底部约束 始终等于最底部的子控件的底部
[self.contentView makeConstraints:^(MASConstraintMaker *make) {
make.leading.top.trailing.equalTo(self);
make.bottom.equalTo(blueLabel);
}];
在获取到lable中的内容后,计算这lable的高度,再来设置label高度. 即在这内容的set方法中完成
- (void)setDText:(NSString *)dText{
_dText = dText;
// NSLog(@"%@",dText);
self.blueLable.text = dText;
// 自动计算这一段文字的高度
NSDictionary *attributes = @{NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue" size:FontSize]};
CGRect rect = [dText boundingRectWithSize:CGSizeMake(self.contentView.frame.size.width - SideMargin * 2, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
[heightCons uninstall];
[self.blueLable updateConstraints:^(MASConstraintMaker *make) {
heightCons = make.height.equalTo(rect.size.height);
}];
}
第二种:cell中含有多个子控件
同样使用Masonry进行控件约束.在这个cell中有1个简单的Img以及多个按钮.将所有的按钮放在bgView上进行九宫格布局.因为bgView上的控件个数不定,所以它的高度不是固定的,需要动态设置.
同样定义一个MASConstraint 属性,记录它的高度
@interface AutoHeightCell (){
MASConstraint *heightCons;
}
@property (nonatomic, weak)UIImageView *icon;
@property (nonatomic ,weak)UIView *bgView;
@end
由上而下做好各控件的约束
// 最下面的控件的底部约束为
[bgView makeConstraints:^(MASConstraintMaker *make) {
make.leading.trailing.equalTo(self.contentView);
make.top.equalTo(icon.bottom);
make.bottom.equalTo(self.contentView);
}];
// 整个contentView的约束同样需要处理
[self.contentView makeConstraints:^(MASConstraintMaker *make) {
make.top.trailing.leading.equalTo(self);
make.bottom.equalTo(bgView.bottom);
}];
在数组的set方法中,此时已经获取到bgView和cell的确定高度. 再对bgView的高度进行重新约束
// 重新计算bgView的高度
[heightCons install];
[self.bgView updateConstraints:^(MASConstraintMaker *make) {
heightCons = make.height.equalTo(btnY + BtnHeight);
}];
控件的个数是不定的,可以添加子控件.利用9宫格布局,在一个bgView上将要添加的按钮都添加上去.最后再添加一个添加的按钮.
/**
* 在背景View 九宫格添加 多个按钮
*/
- (void)addSubBtns{
NSInteger count = self.dataArr.count;
// NSLog(@"%d",count);
CGFloat btnWidth = ([UIScreen mainScreen].bounds.size.width - Margin * (Column + 1)) / 4;
CGFloat btnHeight = BtnHeight;
for (int i = 0; i < count; i++) {
// 行
int row = i / Column;
int col = i % Column;
UIButton *btn = [self creatMyBtnWithText:self.dataArr[i]];
CGFloat btnX = Margin * (col + 1) + btnWidth * col;
CGFloat btnY = Margin * (row + 1) + btnHeight * row;
btn.frame = CGRectMake(btnX, btnY, btnWidth, btnHeight);
btn.tag = TagPar + i;
[btn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];
}
// 最后的添加按钮
UIButton *btn = [self creatMyBtnWithText:@" + "];
[btn addTarget:self action:@selector(addClick) forControlEvents:UIControlEventTouchUpInside];
int row = (int)count / Column;
int col = (int)count % Column;
CGFloat btnX = Margin * (col + 1) + btnWidth * col;
CGFloat btnY = Margin * (row + 1) + btnHeight * row;
btn.frame = CGRectMake( btnX, btnY, btnWidth, BtnHeight);
// NSLog(@"x:%f,y:%f",btnX,btnY);
// 重新计算bgView的高度
[heightCons install];
[self.bgView updateConstraints:^(MASConstraintMaker *make) {
heightCons = make.height.equalTo(btnY + BtnHeight);
}];
}
点击添加按钮调用cell的回调block.在回调block中向输出到cell中的数组中添加内容.同时刷新tableView
/**
* 点击添加按钮
*/
- (void)addClick{
if (self.callBackBlock) {
self.callBackBlock();
}
}
// cell的回调block
cell.callBackBlock = ^{
// NSLog(@"添加按钮");
NSString *str = [NSString stringWithFormat:@"%lu",self.dataArr.count + 1];
[self.dataArr addObject:str];
[self.table reloadData];
};