UITableView动态高度

UITableView在手机app中无处不见,各种需求也是基于tableView做各种花里胡哨的效果,动态cell也是无处不见,身为入门开发者,这也是一个难点。

  • 以下介绍一下我所知道的几种设置动态cell的高度的方法。

1.在- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath中返回想要的高度

这种方法主要是在某个地方计算高度,并且将高度返回。如果使用的是MVC架构,可以写在Model中,但这样可能会使Model变得“胖”起来。使用的是MVVM的话,可以将这个计算过程写在ViewModel中。当然可以直接写在这个代理方法中,但不推荐,因为这样系统每次调用一次这个方法都要计算一次,会很耗性能。
小代码:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:18]};
return [self.array[indexPath.row] boundingRectWithSize:CGSizeMake(300, MAXFLOAT)
                                  options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading
                                  attributes:attributes
                                  context:nil].size.height +
       [self.subArray[indexPath.row] boundingRectWithSize:CGSizeMake(300, MAXFLOAT)
                                  options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading
                                  attributes:attributes
                                  context:nil].size.height
       +15;
}
复制代码

注意:不推荐这样直接写在这个代理方法中,耗性能,当然你设置了估计高度,就当我没说(哭唧唧),我这么写是为了偷懒(嘻嘻)。可以根据MVC或MVVM模式自行调整

2.使用约束

  • 一般来说我在这部分看到网上大部分都是说xib,但是我阅读以后发现xib其实是设置了约束来实现cell的自动高度的,于是我去了解并动手实验了一下,发现cell即使不使用xib,使用纯代码,只要添加了满足条件的约束,那cell也会自动适应高度。

  • 要注意的就是无论是使用纯代码还是xib设置约束时,都要保证这个cell在竖直方向上的约束是完整的。也就是要有一个控件和cell的顶部有约束,还有一个(或者同一个控件)控件和cell的底部有约束。同时在竖直方向上相互控件的约束也是齐全的。

  • 例如如下的图,第一个label和cell顶部有约束,底部和sublabel的顶部也有约束,sublabel的底部和cell的底部有约束。这样就设置完了

    代码如下(此处使用Masonry进行约束):

      -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
      if (self=[super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
          self.titleLabel = [[UILabel alloc]init];
          self.titleLabel.numberOfLines=0;
          self.titleLabel.textColor = [UIColor redColor];
          self.subLabel = [[UILabel alloc]init];
          self.subLabel.numberOfLines=0;
          
          [self addSubview:_titleLabel];
          [self addSubview:_subLabel];
          
          [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
              make.top.equalTo(self).with.offset(5);
              make.left.equalTo(self).with.offset(5);
              make.width.lessThanOrEqualTo(@300);
              make.height.greaterThanOrEqualTo(@0);
          }];
          
          [self.subLabel mas_makeConstraints:^(MASConstraintMaker *make) {
              make.top.equalTo(self.titleLabel.mas_bottom).with.offset(5);
              make.left.equalTo(self).with.offset(5);
              make.width.lessThanOrEqualTo(@300);
              make.height.greaterThanOrEqualTo(@0);
              make.bottom.equalTo(self).with.offset(-5);
          }];
      }
      return self;
    }
    复制代码

另外还要设置上:

tableView.estimatedRowHeight = 44;
tableView.rowHeight = UITableViewAutomaticDimension;
复制代码

这样就基本上设置好了一个动态的cell。xib同理。
最后的效果截图:

关于估算高度estimatedRowHeight

首先看一下官方文档。

  • 关于heightForRow代理方法的官方文档:
    Every time a table view is displayed, it calls tableView:heightForRowAtIndexPath: on the delegate for each of its rows, which can result in a significant performance problem with table views having a large number of rows (approximately 1000 or more).从中可以得知,如果不设置估算高度,那么tableView刚显示时会多次调用这个方法(估计是确定contentSize),那如果我们在这个方法中计算高度,这样就会在数据量大时耗费大量性能。所以这个时候出现了估算高度。
  • 关于estimatedRowHeight的文档: Providing an estimate the height of rows can improve the user experience when loading the table view. If the table contains variable height rows, it might be expensive to calculate all their heights and so lead to a longer load time. Using estimation allows you to defer some of the cost of geometry calculation from load time to scrolling time. 从文档中得知,使用估算高度可以使性能提升,因为这样就不用调用多次heightForRow来进行内部的计算,估算高度直接设置一个常数,这样就不需要进行计算再得出结果,直接得到估算的高度在内部进行计算了。

最后,关于动态高度还有很多方法(例如使用第三方库SDAutolayout)这里也不过多阐述。

集思广益的才能使技术更加好,希望大家多多交流,如果有写错的地方欢迎评论和发表意见。

转载于:https://juejin.im/post/5b67e8e65188251aa14c2412

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值