当需要做一个动态分享的界面例如微博主页、朋友圈等。这时候就需要根据内容计算UITableViewCell的高度了。cell的高度是固定值可以在自定义cell的类里返回cell的高度,但是需要根据内容动态计算cell的高度时则需要创建一个ViewModel,在这个ViewModel取到数据模型时计算子视图的frame以及cell的高度。
先看demo效果
1.分析原型模块
要做一个复杂的界面时,通常把一个界面拆分为几个小的模块从而一一实现
下面把一个cell里的子视图拆分为几个模块。
上图的微博的cell可以拆分为三大块
- 微博主体
- 微博配图
- 工具条
上图有转发内容的微博又可以分为几个模块。
分析好原型的模块之后就可以一一实现
2.创建数据模型
这里我是用plist文件来模拟网络请求获取的数据。
3.创建ViewModel
这一步是最重要的。
- 当ViewModel获取到数据模型时就可以计算cell子视图的frame以及cell的高度
这一步需要在数据模型的setter方法里写
- 定义所有子视图的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地址