简单的TableViewCell高度自适应(只有Label,仅当参考思路)

在iOS开发中或多或少的都会碰到TableViewCell高度自适应,那么今天这篇文章就简单的介绍一下如何给tableViewCell自适应高度 #ViewController copy

@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>{
    UITableView *_tableView;
}

@property (nonatomic, strong) NSMutableArray *modelArr;

@property (nonatomic, assign) CGFloat rowHeight;      //确定cell的高度

@end

@implementation ViewController

- (NSMutableArray *)modelArr{    //初始化model
    if (!_modelArr) {
        NSArray *arr = @[@"大概是因为最近发了一些关于唐诗的文章,有读者发来消息,说家里有孩子马上要上初中,希望我能够推荐书单,“学校的老师只是让不停地抄写,推荐的书她也不爱看,自己选书看。\"",@"但其实,我并不喜欢向人推荐书单。因为在我看来,阅读,其实是很私人化的事情。", @"我一直记得我以前写过我在读大学时看《约翰·克里斯多夫》的情景——我花了大半个学期,费尽心神,才将那本厚厚的书我读了三分之二。但后来,我还是无法坚持下去。那个时候的我,根本不知道那本书要说什么,书里写的内容,现在也毫无印象。",@"“那个变态,居然读《约翰·克里斯多夫》。”有室友说。", @"从此之后的很长时间,我几乎都不再看世界名著。即便看《约翰·克里斯多夫》的时候,我是中文系大二的学生,专业课成绩在班级里名列前茅。"];
        _modelArr = [NSMutableArray arrayWithArray:arr];
    }
    return _modelArr;
}
复制代码

rowHeight

保存计算好的cell的高度,然后在delegate中给cell高度赋值

modelArr

在get方法中初始化模型数组,当使用时就去创建,减少内存开支 #ViewController copy

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    [self createTableView];      //创建tableView
}

static NSString *cellId = @"cellId";
- (void)createTableView{
    _tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
    _tableView.dataSource = self;
    _tableView.delegate = self;
    _tableView.estimatedRowHeight = 130;      //估算cell高度
    [self.view addSubview:_tableView];
    [_tableView registerClass:[MyTableViewCell class] forCellReuseIdentifier:cellId];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.modelArr.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
    cell.text = self.modelArr[indexPath.row];        //给cell赋值
    self.rowHeight = cell.rowHeight;          //返回cell高度
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return self.rowHeight;
}
复制代码

_tableView.estimatedRowHeight = 130;

如果你不加这句话的话TableView也是正常显示,但是当你在返回cell和cell高度的方法中打个断点你会发现在还没返回cell的时候它就在一直调用这个方法

3*self.modelArr.count 次 为什么会有这么多次暂时留一个小尾巴,以后再仔细研究

当调用完这个方法之后再走的是返回cell的方法,然后再走返回高度的方法 所以当你的cell高度差距不确定的时候,最好给cell估算一个大概高度以便提高运行效率

MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId]; cell.text = self.modelArr[indexPath.row]; //给cell赋值 self.rowHeight = cell.rowHeight; //返回cell高度

这里一定是先给cell填充内容然后再获取cell高度,一定要在控制器里保存一下rowHeight 如果你这样写

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return ((MyTableViewCell *)[tableView cellForRowAtIndexPath:indexPath]).rowHeight;
}
复制代码

你会发现所有的cell都挤在了一起,很无语

这里也是一个遗留问题的小尾巴

#MyTableViewCell copy

@interface MyTableViewCell : UITableViewCell

@property (nonatomic, copy) NSString *text;
@property (nonatomic, strong) UIImageView *imageV;
@property (nonatomic, strong) UILabel *label;
@property (nonatomic, assign) CGFloat rowHeight;

@end

@implementation MyTableViewCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        _imageV = [[UIImageView alloc] init];
        _imageV.image = [UIImage imageNamed:@"icon_add_img"];    //气泡图片
        [self.contentView addSubview:_imageV];
        _label = [[UILabel alloc] init];
        _label.numberOfLines = 0;        //设置label行数为最大
        [_imageV addSubview:_label];
    }
    return self;
}

- (void)setText:(NSString *)text{
    _text = text;
    _label.text = text;
    _label.font = [UIFont systemFontOfSize:14.0];
    //计算label高度
    CGRect rect = [text boundingRectWithSize:CGSizeMake(self.frame.size.width - 160, 99999) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName :   [UIFont systemFontOfSize:14.0]} context:nil];
    _label.frame = CGRectMake(80, 10, rect.size.width, rect.size.height);
    _imageV.frame = CGRectMake(30, 10, rect.size.width + 160, rect.size.height + 80);
    [_imageV.image stretchableImageWithLeftCapWidth:150 topCapHeight:0];      //拉伸image
    _rowHeight = CGRectGetMaxY(_imageV.frame) + 20;      //获取cell高度
}

@end
复制代码

CGRect rect = [text boundingRectWithSize:CGSizeMake(self.frame.size.width - 160, 99999) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:14.0]} context:nil];

通过这个方法来计算label的高度,然后返回给cell的rowHeight 把我给的代码复制粘贴运行一下是不是可以了 或许你觉得label不是从x=0的位置开始的,是因为在label的frame位置设置的x=80并且把label加在了imageVIew上了,自己改一下就行了,或者你拿一个气泡图片放上面试试效果也不错

这个图片有些尴尬....毕竟自己做着玩的东西不好意思麻烦美工

运行一下代码试试

感觉还算不错,但是滑动一下试试就有些不对了

其实正确的图片是最后这个,但是第一张图的cell右侧为什么会出现一部分空白地方呢,这也是一个问题(猜想:空白位置是cell删除按钮的宽度)

一篇文章下来出现了很多问题,现在总结一下怎么解决cell高度自适应的问题 1.在cell里面定义一个rowHeight,当传入数据的时候给rowHeight赋值 2.计算label高度可以用到boundingRectWithSize这个方法 3.在创建TableView的时候最好给rowHeight一个估值,以便提高运行效率 4.在控制器中定义一个rowHeight以便保存赋值之后的cell高度 5.聊天气泡图片拉伸方法stretchableImageWithLeftCapWidth

存在的问题 ##为什么返回cell高度的方法会走了3遍的modelArr.count ##为什么不能通过cell直接获取cell高度

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return ((MyTableViewCell *)[tableView cellForRowAtIndexPath:indexPath]).rowHeight;
}
复制代码

##为什么cell右侧会空余出删除按钮的宽度 解决方案:这个确实是历史遗留问题,在layoutSubviews里面更新一下控件的frame就可以了

希望有知道解决方法的大神能给予指点,多谢多谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值