一、添加子控件和传递模型数据
注意:子控件位置不固定,不能写死时就用代码自定义cell
步骤一:将控制器改为继承UITableViewController,然后删除故事板上原来的View,新拖一个TableView,并将Class改为控制器
步骤二:新建一个类WeiboCell,继承自UITableViewCell
步骤三:在控制器实现文件中导入WeiboCell.h
第三个数据源方法
static NSString *ID = @“weibo”;
weiboCell *cell = [tableView dequeueReUsableCellWithIdentifier:ID];
if (cell == nil){
cell = [weiboCell alloc] initWithStyle:UITableCellStyleDefault reuseIdentifier:ID]; //创建的是weiboCell,所以取出来的也应该是这个。
}
return cell;
}
步骤四:在WeiboCell.m中
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)reuseIdentifier
{
self = [super initWithStyle reuseIdentifier:reuseIdentifier];
if (self){
// 添加内部的子控件(不管位置和宽高,把有可能用到的全部加进去)
//1.头像
_icon = [UIImageView alloc] init];
[self.contentView addSubview:_icon] ; //添加子控件要添加到contentView中
//2.昵称
_name = [UILabel alloc] init];
[self.contentView addSubview:_name];
//3.会员图标
_vip = [UIImageView alloc] initWithImage:[UIImage imageNamed:@"vip.png"]];
[self.contentView addSubview:_vip];
//4.时间
_time = [UILabel alloc] init];
[self.contentView addSubview:_time];
//5.来源
_source = [UILabel alloc] init];
[self.contentView addSubview:_source];
//6.微博正文
_content = [UILabel alloc] init];
_content.numberOfLines = 0; //自动换行
[self.contentView addSubview:_content];
//7.配图
_image = [UIImageView alloc] init];
[self.contentView addSubview:_image];
}
步骤五:开发模型并把模型传给cell
已准备好plist文件(Root为Array)
新建一个模型类Weibo,并声明7个属性。
并写2个方法用来把字典传进来变成模型
-(id)initWithDict:(NSDictionary *)dict
{
if (self = [super init]){
self.name = dict[@“name”];
self.time = dict[@“time”];
self.name = dict[@“name”];
self.name = dict[@“name”];
self.name = dict[@“name”];
self.name = dict[@“name”];
self.name = dict[@“name”];
}
}
+(id)weiboWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}
步骤六:在WeiboCell的头文件中传一个微博模型
@class weibo;
@property (nonatomic,strong)weibo weibo;
步骤七:在WeiboCell的实现文件中重写set方法,在这个方法将模型数据赋值给子控件
导入weibo.h
先在类扩展中将7个子控件声明为成员变量,然后将这些控件全部改为下划线
-(void)setWeibo:(weibo *)weibo
{
_weibo = weibo;
//1.头像
_icon.image = [UIImage imageNamed:weibo.icon];
//2.昵称
_name.text = weibo.name;
if (_weibo.vip){
_name.textColor = [UIColor yellowColor];
} else {
_name.textColor = [UIColor blackColor];
}
//3.会员图标
_vip.hidden = !weibo.vip;
//4.时间
_time.text = weibo.time;
//5.来源
_source.text = [NSString stringWithFormat:@"来自%@",_weibo.source];
//6.正文
_content.text = weibo.content;
//7.配图
if (weibo.image){ //有配图
_image.hidden = NO;
_image.image = [UIImage imageNamed:weibo.image];
} else { //没有配图
_image.hidden = YES;
}
}
步骤八:控制器加载plist文件(只需要加载一次,所以在viewDidLoad中)
NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle
pathForResource:@"weibo.plist" ofType:nil]];
导入Weibo.h,并在类扩展中声明一个数组成员变量用来装数据
_weibos = [NSMutableArray array];
for (NSDictionary *dict in array){
[_weibos addObject:(Weibo weiboWithDict:dict)];
}
}
步骤九:实现数据源方法
第二个数据源方法
return _weibos.count;
第三个数据源方法
// 1.去缓存池中取出cell
static NSString *ID = @”weibo“;
WeiboCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
//2.缓存池没有cell,重新创建cell
if (cell == nil){
cell = [[WeiboCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
//3.传递模型数据
cell.weibo = _weibos[indexPath.row];
return cell;
}
二、计算子控件的frame
将设置数据的代码段放到新方法settingData中,然后在set方法中调用这个方法即可
-(void)setWeibo:(Weibo *)weibo
{
_weibo = weibo;
//1.设置微博数据
[self settingData]
//2.设置子控件的frame(x,y,width,height)
[self settingSubViewFrame];
}
-(void)settingSubviewFrame
{
// 1. 头像
CGFloat iconX = kCellBorder;
CGFloat iconY = kCellBorder;
_icon.frame = CGRectMake(iconX,iconY,kIconMH,kIconMH);
// 2. 昵称
CGFloat nameX = CGRectGetMaxX(_icon.frame)+ kCellBorder;
CGFloat nameY = iconY;
//计算用户名称的尺寸
CGSize nameSize = [_weibo.name sizeWithFont:_name.font];
_icon.frame = CGRectMake(nameX,nameY,nameSize.width,nameSize.height)
//3.vip
CGFloat vipX = CGRectGetMaxX(_name.frame)+ kCellBorder;
CGFloat vipY = nameY;
_icon.frame = CGRectMake(vipX,vipY,kvipMH,kvipMH);
//4.时间
CGFloat timeX = nameX;
CGFloat timeY = CGRectGetMaxY(_name.frame)+ kCellBorder;
CGSize timeSize = [_weibo.time sizeWithFont:_time.font];
_time.frame = CGRectMake(timeX,timeY,timeSize.width,timeSize.height);
//5.来源
CGFloat sourceX = CGRectGetMaxX(_time.frame)+ kCellBorder;
CGFloat sourceY = timeY;
NSString *sourceText = [NSString stringWithFormat:@"来自%@",_weibo.source];
CGSize sourceSize = [sourceText sizeWithFont:_source.font];
_source.frame = CGRectMake(sourceX,sourceY,sourceSize.width,sourceSize.height);
//6.正文
CGFloat contentX = iconX;
CGFloat contentY = MAX(CGRectGetMaxY(_time.frame),CGRectGetMaxY(_icon.frame))+ kCellBorder;
CGFloat contentW = self.frame.size.width - 2*kCellBorder;
//计算文字尺寸(显示文字的宽度)
CGSize contentSize = [_weibo.content sizeWithFont:_content.font constrainedToSize:CGSizeMake(contentW,MAXFLOAT)];
_content.frame = CGRectMake(contentX,contentY,contentW,contentSize.height) ;
//7.配图\计算cell的高度
CGFloat cellHeight = 0;
if (_weibo.image){ //有配图
CGFloat imageX = contentX;
CGFloat imageY = CGRectGetMaxY(_content.frame)+ kCellBorder;
_image.frame = CGRectMake(imageX,imageY,kImageWH,kImageWH);
CGFloat cellHeight = CGRectGetMaxY(_image.frame)+ kCellBorder;
} else {
CGFloat cellHeight = CGRectGetMaxY(_content.frame)+ kCellBorder;
}
因为是先调用代理方法再调用set方法,所以在set方法中计算高度然并卵
新建1个模型WeiboFrame用来存放一个cell内部所有子控件的frame
声明属性如iconF等,还有一个属性cellHeight和一个属性Weibo(@class Weibo)
将计算frame的一大串代码放到这个模型的实现文件中的setWeibo方法中
只要你把这个Weibo属性给它,它就会帮你计算frame
开始计算cell高度
//根据模型数据获得cell的高度
WeiboFrame *f = [[WeiboFrame alloc] init];
f.weibo = _weibos[indexPath.row];
return f.cellHeight;
*WeiboCell中不需要拥有Weibo属性,而是拥有WeiboFrame属性,这样既可以拿到Weibo数据,又可以拿到WeiboFrame数据
*修改settingSubviewFrame方法的代码
//1.头像
_icon.frame = _weiboFrame.iconF;
......
步骤总结
1>新建一个UITableViewCell的子类----WeiboCell
2>在创建cell的时候(initWithStyle:reuseIndetifier:方法中)添加cell内部需要使用的子控件(设置只需要设置一次的在init方法里设置)
(注意:只管创建添加子控件,先不要去管子控件的位置和尺寸)
3>新建一个模型类----Weibo,增加对应的数据属性
4>给WeiboCell增加一个Weibo模型属性,在拿到Weibo模型数据的同时设置子控件的属性
5>重写setWeibo:方法:在这里面取出Weibo模型的数据显示到子控件上
补充:
在viewDidLoad中注册一个xib文件,如果tableView通过标识在缓存池中没有取到可循环利用的Cell,就会加载MyCell1.xib文件来创建cell
[self.tableView registerNib[UINib nibWithNibName:@"MyCell1" bundle:nil]
forCellReuseIdentifier:@"Cell"];
如此一来,就不需要再第3个数据源方法中判断cell是否为nil了。