在项目开发中,我们难免会遇到tableView的Cell的高度自适应,在这里就介绍一下经常出现的三种情况
1、cell根据Label的高度而改变
有两种方法:
方法一:可视化添加约束实现(即定制Cell)在storyboard和xib的原理是一样的,这里以storyboard为例
要根据Label 的内容自适应Cell的高度,那么就必须固定宽度才能计算高度,这里通过添加Label两边的约束,根据屏幕的大小来固定宽度的。
宽度固定了,那么再给Label添加上下约束,如上图,这样系统就可以根据上下约束的值和Label的高度计算得出Cell的高度了,这里要注意的有两点:1.Label的行数要设置为0,才能自动换行。2.因为Cell的高度是根据zongse框Label的高度计算高度,使用只能给Label添加上下约束,而“内容”的label是不能添加约束的,不然就冲突了
当然定制好Cell之后,还需添加一句代码
_tableView.rowHeight=UITableViewAutomaticDimension;//自动换行(iOS8.0之后是默认值,不用再设置)
_tableView.estimatedRowHeight = 100;//预设高度(注意并不是最小高度)只是为了设置contentsize
方法二:代码实现 ,实现如下图效果
Label显示内容:
_dataString=@"好好学习好好学习好好学习好好学习好好学习好好学习好好学习好好学习好好学习好好学习好好学习好好学习好好学习好好学习好好学习好好学";
在tableView的HeightForRow代理方法中,动态改变高度
- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath{
//设定字体格式
NSDictionary*fontDt = [NSDictionarydictionaryWithObjectsAndKeys: [UIFontsystemFontOfSize:17],NSFontAttributeName,nil];
//设定宽度计算高度
CGRect rect = [_dataString boundingRectWithSize:CGSizeMake(self.view.frame.size.width-101,0)options:NSStringDrawingUsesLineFragmentOrigin attributes:fontDt context:nil];
return rect.size.height+22+2;
//22是Label 上下约束之和
//2是NSStringDrawingUsesLineFragmentOrigin属性不包括线条的宽度,所以这里需要添加上下两条线条的宽度
}
2、Cell根据TextView输入的内容动态改变高度
同样实现方法也分两种
方法一:在storyboard定制Cell中实现
分两步:
第一步:设置textView的delegate的为Cell,并且在定制的Cell类中的.m 文件中实现 textView的代理方法,代码如下
- (void)textViewDidChange:(UITextView*)textView{
if([self.delegaterespondsToSelector:@selector(textViewCell: didChangeText:)]) {
[self.delegatetextViewCell:selfdidChangeText:textView.text];
}
CGRectbounds = textView.bounds;
CGSizemaxSize =CGSizeMake(bounds.size.width,CGFLOAT_MAX);
CGSizenewSize = [textViewsizeThatFits:maxSize];
bounds.size= newSize;
textView.bounds= bounds;
//让table view重新计算高度并刷新
UITableView*tableView = [selftableView];
[tableViewbeginUpdates];
[tableViewendUpdates];
}
- (UITableView*)tableView{
UIView*tableView =self.superview;
while(![tableViewisKindOfClass:[UITableViewclass]] && tableView) {
tableView = tableView.superview;
}
return(UITableView*)tableView;
}
最后在VC方法中设置tableView自适应高度就可以了,添加以下代码
self.tableView.estimatedRowHeight = 100;
self.tableView.rowHeight = UITableViewAutomaticDimension;
注意:在VC中不能实现tableView的heightForCell代理方法,因为前面已经设置了是自适应高度的,所以系统会自己计算
第二种:使用tableView的heightForCell代理方法实现(这也是会经常用到的,一个VC中有可能存在多个tableView或多种Cell)
在cell的定制中,除了要添加textView的上下左右约束外,也是跟第一种方法一样,在设置以下事项
然后在新建的Cell类中,没有什么特殊设置代码要添加,就跟平时一样就可以了,该拉线就拉线
重点在VC中textView的delegate方法中和tableView的heightForCell方法中,废话不多说,直接看代码
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *heightString = [_heightRecordDt objectForKey:indexPath];
//设置最小高度
if (heightString.floatValue < 44) {
return 44;
}else{
return heightString.floatValue;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];
cell.MyTextView.delegate = self;
cell.MyTextView.text = [_textViewStringDt objectForKey:indexPath];
cell.MyTextView.tag = indexPath.section*1000 + indexPath.row;
cell.MyTextView.scrollEnabled = NO;
return cell;
}
#pragma mark - textView delegate
- (void)textViewDidChange:(UITextView *)textView{
NSIndexPath *index = [NSIndexPath indexPathForRow:textView.tag%1000 inSection:textView.tag/1000];
CGRect rect1 = textView.frame;
CGSize maxSize = CGSizeMake(rect1.size.width, CGFLOAT_MAX);
CGSize newSize = [textView sizeThatFits:maxSize];
rect1.size = newSize;
textView.frame = rect1;
//保存内容,便于cell的复用
[_textViewStringDt setObject:textView.text forKey:index];
NSString *heightString = [_heightRecordDt objectForKey:index];
//判断:当高度发生改变的时候才刷新cell
//单独刷新一个cell
if (rect1.size.height != heightString.floatValue) {
//保存最新高度
[_heightRecordDt setObject:[NSString stringWithFormat:@"%f",rect1.size.height+12] forKey:index];
[_tableView beginUpdates];
[_tableView endUpdates];
}
}
完整的github:demo
https://github.com/ZeroOnetoo/MZTableViewCell
欢迎各位码民吐槽,集思广益,会将最新的技术更新!!
请多多点赞,谢谢!!