在使用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;
}