iOS:根据内容动态计算高度的UITableViewCell

当需要做一个动态分享的界面例如微博主页、朋友圈等。这时候就需要根据内容计算UITableViewCell的高度了。cell的高度是固定值可以在自定义cell的类里返回cell的高度,但是需要根据内容动态计算cell的高度时则需要创建一个ViewModel,在这个ViewModel取到数据模型时计算子视图的frame以及cell的高度。

先看demo效果


1.分析原型模块

要做一个复杂的界面时,通常把一个界面拆分为几个小的模块从而一一实现
下面把一个cell里的子视图拆分为几个模块。

iOS:根据内容动态计算高度的UITableViewCell_第1张图片

上图的微博的cell可以拆分为三大块

  • 微博主体
  • 微博配图
  • 工具条
iOS:根据内容动态计算高度的UITableViewCell_第2张图片

上图有转发内容的微博又可以分为几个模块。
分析好原型的模块之后就可以一一实现

2.创建数据模型

这里我是用plist文件来模拟网络请求获取的数据。


iOS:根据内容动态计算高度的UITableViewCell_第3张图片
iOS:根据内容动态计算高度的UITableViewCell_第4张图片
.m文件
iOS:根据内容动态计算高度的UITableViewCell_第5张图片
.h文件

3.创建ViewModel

这一步是最重要的。

  • 当ViewModel获取到数据模型时就可以计算cell子视图的frame以及cell的高度
    这一步需要在数据模型的setter方法里写
iOS:根据内容动态计算高度的UITableViewCell_第6张图片
.h
iOS:根据内容动态计算高度的UITableViewCell_第7张图片
.m
  • 定义所有子视图的Frame
@class Moments;
@interface MomentViewModel : NSObject

/**
 *  数据模型
 */
@property (nonatomic ,strong) Moments *moment;

/**
 *  主体Frame
 */
@property (nonatomic ,assign) CGRect momentsBodyFrame;

//昵称Frame
@property (nonatomic ,assign) CGRect bodyNameFrame;
//头像Frame
@property (nonatomic ,assign) CGRect bodyIconFrame;
//时间Frame
@property (nonatomic ,assign) CGRect bodyTimeFrame;
//正文Frame
@property (nonatomic ,assign) CGRect bodyTextFrame;
//图片Frame
@property (nonatomic ,assign) CGRect bodyPhotoFrame;

/**
 *  工具条Frame
 */
@property (nonatomic, assign) CGRect momentsToolBarFrame;

//点赞Frame
@property (nonatomic ,assign) CGRect toolLikeFrame;
//评论Frame
@property (nonatomic ,assign) CGRect toolCommentFrame;

/**
 *  cell高度
 */
@property (nonatomic ,assign) CGFloat cellHeight;

@end
  • 计算子视图的frame(详细在代码里)

4.Model转ViewModel

在ViewController里把Model转为ViewModel

- (NSMutableArray *)moments{
    if (!_moments) {
        _moments = [NSMutableArray array];
        _moments = [Moments moments];
    }
    return _moments;
}

- (NSMutableArray *)momentFrames{
    if (!_momentFrames) {
        _momentFrames = [NSMutableArray array];
        //数据模型 => ViewModel(包含cell子控件的Frame)
        for (Moments *moment in self.moments) {
            MomentViewModel *momentFrame = [[MomentViewModel alloc] init];
            momentFrame.moment = moment;
            [self.momentFrames addObject:momentFrame];
        }
    }
    return _momentFrames;
}

5.给自定义UITableViewCell赋值ViewModel

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    MomentsTableViewCell *cell = [MomentsTableViewCell momentsTableViewCellWithTableView:tableView];
    cell.momentFrames = self.momentFrames[indexPath.section];
    return cell;
}

6.优化

当数据很多列表过长的时候优化就势在必行了,可以往以下几个方面考虑

  • 当用户滑动时不加载图片(新浪微博的方法)
  • 异步加载图片
  • 尽量不用系统提供的方法加载圆形头像,而采用加载圆形图片
  • 使用reloadSection进行局部更新

最后源码:
github地址

你可能感兴趣的:(iOS:根据内容动态计算高度的UITableViewCell)