好啦,这是一个老生常谈的问题。真的,有时候把人气得想去搞安卓,安卓就没得这码子事~
方案有很多,我这里提供三种方案。其实每种自适应高度的方法都有比较适合自己的情景,比如cell里面就一个label文本,其他是按钮或者图片这些,布局比较简单的,就使用简单的方法。又比如你要自己搭建个朋友圈的功能,朋友圈又有文字,又有图片,又有评论这种比较复杂的UI,自己去解决吧。。。本文的高度还没达到。
方案一:使用系统自带的方法,封装一个计算高度的方法。方法的参数为,你要计算的字符串,你想要的字体大小,你先想要的文本宽度。(其实现在已经很少有人用了,方法过于原始,一遇到复杂的情况计算起来消耗性能不说,算法也麻烦)
//文本自适应
- (CGSize)sizeWithString:(NSString *)string
constraintWidth:(CGFloat)constrainWidth
font:(UIFont *)font {
//给size自变量赋初始值
CGSize size = CGSizeZero;
CGRect rect = [string boundingRectWithSize:CGSizeMake(constrainWidth, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil];
size = rect.size;
return size;
}
方案二:为系统的UILabel控件扩展类方法,让UILabel自己的方法去计算高度。(方法比较巧妙,有些人使用)
.h文件
#import
@interface UILabel (LabelHeightAndWidth)
//UILabel通过调用此方法计算出文本的高度
+ (CGFloat)getHeightByWidth:(CGFloat)width title:(NSString *)title font:(UIFont*)font;
@end
.m文件
#import "UILabel+LabelHeightAndWidth.h"
@implementation UILabel (LabelHeightAndWidth)
+ (CGFloat)getHeightByWidth:(CGFloat)width title:(NSString *)title font:(UIFont *)font
{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, 0)];
label.text = title;
label.font = font;
label.numberOfLines = 0;
[label sizeToFit];
CGFloat height = label.frame.size.height;
return height;
}
@end
方案三:这里推荐一个三方,UITableView+FDTemplateLayoutCell它就是用来计算比较复杂的cell的高度的,性能可以和代码量不多,为我们省了很多事(很多人使用)。使用方法如下:
1.使用Pods导入这个三方类库,pod ‘UITableView+FDTemplateLayoutCell’
2.第二步,必须注册一下,无论你使用的什么布局方式。
(void)viewDidLoad {
[super viewDidLoad];
[self getSources];
[self.view addSubview:self.tableView];
UIView *superView = self.view;
[_tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(superView.mas_left);
make.right.mas_equalTo(superView.mas_right);
make.top.mas_equalTo(superView.mas_top);
make.bottom.mas_equalTo(superView.mas_bottom).offset(0);
}];
// self.tableView.fd_debugLogEnabled = YES;
//必须注册一下,不然要报错
[self.tableView registerClass:[ZWTableViewCell class] forCellReuseIdentifier:@”ZWCell”];
}
3.创建一个数据模型,我这里就定义一个字符串。我默认你使用了数据模型,遵循了MVC模式。
#import
@interface ContentModel : NSObject
@property (nonatomic, copy)NSString *textContent;
@end
4.自定义UITableViewCell
.h文件
#import
#import "ContentModel.h"
@interface ZWTableViewCell : UITableViewCell
@property (nonatomic, strong)UILabel *label;
@property (nonatomic, strong)ContentModel *Model;
@end
.m文件
#import "ZWTableViewCell.h"
#import "Masonry.h"
@implementation ZWTableViewCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
[self.contentView addSubview:self.label];
//需要注意的是,使用这个自适应高度的三方,不要在layoutSubviews中设置约束。
UIView *superView = self.contentView;
[_label mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(superView.mas_left).offset(5);
make.top.mas_equalTo(superView.mas_top).offset(5);
make.right.mas_equalTo(superView.mas_right).offset(-5);
make.bottom.mas_equalTo(superView.mas_bottom).offset(-5);
}];
}
return self;
}
-(void)setModel:(ContentModel *)Model{
_Model = Model;
self.label.text = Model.textContent;
}
//使用Masonry需要实现这个方法,下面加的10是因为label距离上面为5,距离下面为5,需要加上10.
- (CGSize)sizeThatFits:(CGSize)size{
CGFloat cellHeight = 0;
//如果有其他控件,也如法炮制。
cellHeight += [self.label sizeThatFits:size].height;
//这是计算各个控件之间的间隙。
cellHeight += 10;
return CGSizeMake(size.width, cellHeight);
}
- (UILabel *)label{
if (!_label) {
_label = [[UILabel alloc]init];
_label.textAlignment = 0;
_label.numberOfLines = 0;
_label.font = [UIFont systemFontOfSize:20];
_label.backgroundColor = [UIColor redColor];
}
return _label;
}
@end
5.在你的控制器中,将Model模型传进去。使用这个框架自带的方法。在tableView的高度协议方法中实现。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//使用这个框架需要这个。
return [tableView fd_heightForCellWithIdentifier:@"ZWCell" cacheByIndexPath:indexPath configuration:^(ZWTableViewCell *cell) {
cell.Model = self.listArray[indexPath.row];
}];
}