在使用UITableView做开发时,常常会遇到 系统提供的样式无法满足项目需求的情况,这时就需要根据需求来自定义cell。
自定义cell有两种方式:
· 通过xib自定义cell(适用于cell中子控件个数固定、cell样式统一的结构,例如:商品的列表页面)
· 通过代码自定义cell(适用于cell中子控件个数不固定、cell样式不统一的结构,例如:微博列表)
通过代码创建自定义cell:
1.新建一个继承自UITableViewCell的类
2.先在构造方法initWithStyle: reuseIdentifier:
·添加所有需要显示的子控件(不需要设置数据和frame,子控件要添加到contentView中)
·进行子控件一次性的属性设置(有些属性只需要设置一次 例如:字体、固定的图片等)
/**
构造方法在创建对象时调用
一般在这个方法中添加需要使用的子控件
*/
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//1.头像
UIImageView *iconView = [[UIImageView alloc] init];
self.iconView = iconView;
[self.contentView addSubview:iconView];
//2.昵称
UILabel *nameView = [[UILabel alloc] init];
nameView.font = NameFont;
[self.contentView addSubview:nameView];
self.nameView = nameView;
//3.会员图标
UIImageView *vipView = [[UIImageView alloc] init];
vipView.image = [UIImage imageNamed:@"vip"];
[self.contentView addSubview:vipView];
self.vipView = vipView;
//4.正文
UILabel *textView = [[UILabel alloc] init];
textView.numberOfLines = 0;
textView.font = TextFont;
[self.contentView addSubview:textView];
self.textView = textView;
//5.配图
UIImageView *pictureView = [[UIImageView alloc] init];
[self.contentView addSubview:pictureView];
self.pictureView = pictureView;
}
return self;
}
3.提供2个模型
·数据模型:存放文字、图片等数据
重写构造方法:通过字典初始化对象
+(instancetype)statusWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}
-(instancetype)initWithDict:(NSDictionary *)dict
{
if (self = [super init]) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
·frame模型:存放数据模型,存放所有子控件的frame数据和 cell 的最终高度
4.cell拥有一个frame模型属性(不要直接拥有数据模型,frame模型中包括数据模型和frame数据)
5.重写frame模型属性的setter,在这个方法中设置子控件的数据和frame
- (void)setStatus:(Status *)status
{
//设置数据模型数据
_status = status;
//计算子控件的frame
//子控件之间的间距
CGFloat padding = 10;
//1.头像
CGFloat iconX = padding;
CGFloat iconY = padding;
CGFloat iconH = 35;
CGFloat iconW = 35;
_iconFrame = CGRectMake(iconX, iconY, iconW, iconH);
}
6.frame模型数据的初始化,通过懒加载的方式(每一个cell对应的frame模型只加载一次)
控制器中拥有一个frame模型属性
/**
懒加载数据
*/
-(NSArray *)statusesFrame
{
if (_statusesFrame == nil) {
//初始化数据
NSString *path = [[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil];
NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];
NSMutableArray *statusFrameArray = [NSMutableArray array];
for (NSDictionary *dict in dictArray) {
//创建status模型
Status *status = [Status statusWithDict:dict];
//创建statusFrame模型
StatusFrame *statusFrame = [[StatusFrame alloc] init];
statusFrame.status = status;
[statusFrameArray addObject:statusFrame];
}
_statusesFrame = statusFrameArray;
}
return _statusesFrame;
}
7.实现TableView的数据源方法
/**
数据有多少行
*/
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.statusesFrame.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//1.创建cell
StatusCell *cell = [StatusCell cellWithTableView:tableView];
//2.传递模型数据给cell
cell.statusFrame = self.statusesFrame[indexPath.row];
return cell;
}
8.实现TableView的代理方法,设置每个cell的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
StatusFrame *statusFrame = self.statusesFrame[indexPath.row];
return statusFrame.cellHeight;
}