TableView表格展示信息,在项目中会非常频繁的使用到,所以我们会经常与TableViewCell打交道。在比较简单的展示的时候,系统提供的UITableViewCell就足够我们使用,但是在较为复杂的展示界面的时候(例如新浪微博的界面),我们就需要自己定制一个特定样式的Cell来满足项目需求,本文的目的,就是要讲解如何去定义复杂的Cell.
下面我们就以新浪微博的Cell为例,
这篇文章介绍的是通过创建Frame模型的方法,来实现自定义复杂Cell的。(下一篇我会介绍第二种方法)
第一大步:
1,字典转模型
网络请求回来的数据,首先通过字典转模型的方法转换为模型对象,假设模型类是CellModel继承自NSOject。
CellModel中保存这cell上面要展示的所有内容信息。转换结果得到一个模型数组cellModelArray.
2,模型转换为Frame模型
新建一个继承自NSOject的Frame模型类,假设为CellModelFrame。
1,CellModelFrame类中添加一个CellModel属性,使得CellModelFrame拥有CellModel。
2,CellModelFrame类中添加一个Cell高度属性cellHeight,
3,Cell上面所有子控件的frame属性,属性类型是CGRect。在这里就举一个例子headImageFrame。
@interface CellModelFrame : NSObject
@property (nonatomic, strong) CellModel *cellModel;//模型属性
@property (nonatomic, assign) CGFloat cellHeight;//cell高度
@property (nonatomic, assign) CGRect contentLabelF;//子控件Label的frame
......
@end
在Frame模型类中重写setCellModel:(CellModel *)cellModel{}方法,在重写的setter方法中计算cell上面所有子控件的frame和cell本身的高度。
@implementation CellModelFrame
- (void)setCellModel:(CellModel *)cellModel{
_cellModel = cellModel;
//在这里计算Cell上面每一个子控件的frame,例如:
CGFloat contentLabelX = 10;
CGFloat contentLabelY = 10;
CGSize contentLabelSize = [cellModel.text boundingRectWithSize:CGSizeMake([UIScreen mainScreen].bounds.size.width, MAXFLOAT) options:0 attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14]} context:nil]; //CellModel模型类里面有个NSString类型的属性text
self.contentLabelF = (CGRect){{contentLabelX,contentLabelY},contentLabelSize};
//上面只是简单的举例计算了一个子控件的frame,实际项目中,所有的子控件frame都在这里计算。
}
@end
有了Frame模型类之后, 模型数组转换为Frame模型数组
NSMutableArray *cellModelFrames = [NSMutableArray array]; //cellModelFrames为Frame模型数组
for (CellModel *cellModel in cellModelArray) {
//初始化frame模型,设置frame模型身上的数据模型的值
CellModelFrame *frame = [[CellModelFrame alloc] init];
frame.cellModel = cellModel;
[cellModelFrames addObject:frame];
}
模型转换为Frame模型之后,那么Frame模型对象中的所有属性都被赋值了。到这里Frame模型已经准备好了,接下来把Frame模型直接赋值给自定义的Cell就可以了。
第二大步:
1,自定义Cell
自定义StatusCell类中,声明一个statusFrame模型属性
@interface StatusCell : UITableViewCell
//cell里面保留CellModelFrame模型
@property (nonatomic, strong) CellModelFrame *modelFrame;
@end
然后重写initWithStyle:方法,在方法中,添加所有需要的子控件
再重写setFrame:(CellModelFrame *)frame方法,在这个方法里面给所有子控件的frame属性赋值,要展示的内容赋值。
- (void)setModelFrame:(CellModelFrame *)modelFrame{
_modelFrame = modelFrame;
//例如,要给contentLabel赋值
self.contentLabel.frame =modelFrame.contentLabelF;
self.contentLabel.text = modelFrame.status.text;
//所有的子控件都在这里赋frame和显示内容的值。
}
2,在tableview的数据源方法中,给cell 赋值
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
......
CellModelFrame *modelFrame = self.cellModelFrames[indexPath.row];
//设置值
cell.modelFrame = modelFrame;
...
return cell;
}
3,在tableview的数据源方法中,返回cell 的高度值
//返回每一个cell的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
CellModelFrame *modelFrame = self.cellModelFrames[indexPath.row];
return modelFrame.cellHeight;
}
到这里所有主要的步骤都完成了。