最终效果图:
动态效果截图:
BeyondTableViewController.h
// // BeyondTableViewController.h // 15_代码自定义cell_weibo // // Created by beyond on 14-7-29. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import <UIKit/UIKit.h> @interface BeyondTableViewController : UITableViewController @end
BeyondTableViewController.m
// // BeyondTableViewController.m // 15_代码自定义cell_weibo // // Created by beyond on 14-7-29. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import "BeyondTableViewController.h" #import "Weibo.h" #import "WeiboFrames.h" #import "WeiboCell.h" @interface BeyondTableViewController () { // 从plist文件中加载的所有weiboFrames(因为它已经含有一个weibo成员),返回所有的对象组成的数组 NSMutableArray *_weiboFrames; } @end @implementation BeyondTableViewController // 隐藏顶部的状态栏 - (BOOL)prefersStatusBarHidden { return YES; } - (void)viewDidLoad { [super viewDidLoad]; NSLog(@"view did load---"); // 初始化 对象数组 _weiboFrames = [NSMutableArray array]; // 调用自定义方法,将plist转成对象数组 [self plistToObjects]; } // 自定义方法,将plist转成对象数组 - (void)plistToObjects { // sg_bundle模板代码,1,获得.app主要的包;2,返回主要的包中某个文件的fullPath全路径 NSBundle *mainBundle = [NSBundle mainBundle]; NSString *fullPath = [mainBundle pathForResource:@"weibo.plist" ofType:nil]; // 从plist文件中根据全路径,返回字典数组 NSArray *arrayWithDict = [NSArray arrayWithContentsOfFile:fullPath]; // 模型的类方法返回对象,参数只要一个字典数组即可 for (NSDictionary *dict in arrayWithDict) { // 参数只要字典,这样一来,控制器就不用知道太多东西了 WeiboFrames *frames = [[WeiboFrames alloc]init]; // ***********设置的WeiboFrames的成员weibo的同时,进行了复杂的计算,并填充了WeiboFrames各个frame成员 frames.weibo = [Weibo weiboWithDict:dict]; // 添加到对象数组 [_weiboFrames addObject:frames]; } } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // 返回对象数组的长度 return _weiboFrames.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // 1,从池中取 WeiboCell *cell = [tableView dequeueReusableCellWithIdentifier:[WeiboCell cellID]]; // 2,取不到的时候,创建一个纯洁的WeiboCell if (cell == nil) { cell = [[WeiboCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[WeiboCell cellID]]; } // 3,设置独一无二的数据 WeiboFrames *weiboFrames = [_weiboFrames objectAtIndex:indexPath.row]; cell = [cell cellWithWeiboFrames:weiboFrames]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { // WeiboFrames的成员有:weibo数据模型对象,以及根据数据模型计算出来的所有的frames,以及最大的Y即对应数据模型的行高 WeiboFrames *frames = [_weiboFrames objectAtIndex:indexPath.row]; return frames.maxY; } // 取消默认点击后,蓝色高亮背景 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; } @end
Weibo.h
// // Weibo.h // 15_代码自定义cell_weibo // // Created by beyond on 14-7-29. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import <Foundation/Foundation.h> // 把要用到的字体抽成宏 // 姓名 用的字体 #define kNameFnt [UIFont fontWithName:@"HelveticaNeue" size:24.0f] // 内容 用的字体 #define kContentFnt [UIFont fontWithName:@"HelveticaNeue" size:18.0f] // 来自客户端 用的字体 #define kClientFnt [UIFont fontWithName:@"HelveticaNeue" size:16.0f] // 发表时间 用的字体 #define kPostTimeFnt [UIFont fontWithName:@"HelveticaNeue" size:14.0f] // 分享次数 用的字体 #define kShareFnt [UIFont fontWithName:@"HelveticaNeue" size:16.0f] // 评论次数 用的字体 #define kCommentFnt [UIFont fontWithName:@"HelveticaNeue" size:16.0f] // 仅用于 封闭实体数据 @interface Weibo : NSObject // UI控件用weak,字符串用copy,其他对象用strong // 头像 @property (nonatomic,copy) NSString *headImg; // 是不是大V @property (nonatomic,assign) BOOL isVIP; // 名字 @property (nonatomic,copy) NSString *name; // 发表时间 @property (nonatomic,copy) NSString *postTime; // 正文内容 @property (nonatomic,copy) NSString *content; // 大图片 @property (nonatomic,copy) NSString *bigImg; // 来自客户端 @property (nonatomic,copy) NSString *client; // 分享次数 @property (nonatomic,copy) NSString *shareNum; // 评论次数 @property (nonatomic,copy) NSString *commentNum; // 类方法,字典 转 对象 类似javaBean一次性填充 + (Weibo *)weiboWithDict:(NSDictionary *)dict; // 对象方法,设置对象的属性后,返回对象 - (Weibo *)initWithDict:(NSDictionary *)dict; @end
Weibo.m
// // Weibo.m // 15_代码自定义cell_weibo // // Created by beyond on 14-7-29. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import "Weibo.h" @implementation Weibo // 类方法,字典 转 对象 类似javaBean一次性填充 + (Weibo *)weiboWithDict:(NSDictionary *)dict { return [[self alloc]initWithDict:dict]; } // 对象方法,设置对象的属性后,返回对象 - (Weibo *)initWithDict:(NSDictionary *)dict { // 必须先调用父类NSObject的init方法 if (self = [super init]) { // 设置对象自己的属性 /* 麻烦 // 头像 self.headImg = dict[@"headImg"]; // 是不是大V self.isVIP = [dict[@"isVIP"] boolValue]; // 名字 self.name = dict[@"name"]; // 发表时间 self.postTime = dict[@"postTime"]; // 正文内容 self.content = dict[@"content"]; // 大图片 self.bigImg = dict[@"bigImg"]; // 来自客户端 self.client = dict[@"client"]; // 分享次数 self.shareNum = dict[@"shareNum"]; // 评论次数 self.commentNum = dict[@"commentNum"]; */ // 通过遍历 将 字典 赋值为对象各个属性 for (NSString *key in dict) { [self setValue:dict[key] forKeyPath:key]; } // 一次性 将 字典 赋值为对象各个属性 // [self setValuesForKeysWithDictionary:dict]; } // 返回填充好的对象 return self; } @end
WeiboFrames.h
// // WeiboFrames.h // 15_代码自定义cell_weibo // // Created by beyond on 14-7-29. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import <Foundation/Foundation.h> @class Weibo; // 控件与控件之间的外边距 #define kMargin 7 // 头像的高宽 #define kHeadImgHW 85 // isVIP的高宽 #define kIsVIPHW 17 // 分享图片的高宽 #define kShareHW 20 // 评论图片的高宽 #define kCommentHW 20 // 专门保管 一个数据模型对象,以及根据其内容计算出来的所有的frames,包括maxY,即行高 @interface WeiboFrames : NSObject // 最大的Y值,就是行高 @property (nonatomic,assign,readonly) CGFloat maxY; // 重要,拥有一个成员:Weibo对象,目的是在控制器中,传递weibo对象进来之后,可以通过此Weibo模型对象的数据,计算出所有的frames @property (nonatomic,strong) Weibo *weibo; // 头像 的frame @property (nonatomic,assign,readonly) CGRect headImgFrame; // 是不是大V 的frame @property (nonatomic,assign,readonly) CGRect isVIPFrame; // 名字 的frame @property (nonatomic,assign,readonly) CGRect nameFrame; // 发表时间 的frame @property (nonatomic,assign,readonly) CGRect postTimeFrame; // 正文内容 的frame @property (nonatomic,assign,readonly) CGRect contentFrame; // 大图片 的frame @property (nonatomic,assign,readonly) CGRect bigImgFrame; // 来自客户端 的frame @property (nonatomic,assign,readonly) CGRect clientFrame; // 分享图片 的frame @property (nonatomic,assign,readonly) CGRect shareImgFrame; // 分享次数 的frame @property (nonatomic,assign,readonly) CGRect shareNumFrame; // 评论图片 的frame @property (nonatomic,assign,readonly) CGRect commentImgFrame; // 评论次数 的frame @property (nonatomic,assign,readonly) CGRect commentNumFrame; @end
WeiboFrames.m
// // WeiboFrames.m // 15_代码自定义cell_weibo // // Created by beyond on 14-7-29. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import "WeiboFrames.h" #import "Weibo.h" @implementation WeiboFrames // WeiboFrames类 唯一的一个方法:设置weibo的时候,可以通过其数据,计算出各个frames,以及最大的Y,也就是行高 - (void)setWeibo:(Weibo *)weibo { _weibo = weibo; // 具体的计算各个frames的代码,放在这儿~~~ // 1,头像的frame // 头像的x CGFloat headImgX = kMargin; // 头像的y CGFloat headImgY = kMargin; // 头像的H CGFloat headImgH = kHeadImgHW; // 头像的W CGFloat headImgW = kHeadImgHW; _headImgFrame = CGRectMake(headImgX, headImgY, headImgH, headImgW); // 2,isVIP的frame // isVIP的x CGFloat isVIPX = CGRectGetMaxX(_headImgFrame) - 0.5*kIsVIPHW; // isVIP的y CGFloat isVIPY = CGRectGetMaxY(_headImgFrame) - 0.5*kIsVIPHW; // isVIP的H CGFloat isVIPH = kIsVIPHW; // isVIP的W CGFloat isVIPW = kIsVIPHW; _isVIPFrame = CGRectMake(isVIPX, isVIPY, isVIPH, isVIPW); // 3,名字的frame // 名字的x CGFloat nameX = CGRectGetMaxX(_headImgFrame) + kMargin; // 名字的y CGFloat nameY = headImgY; // label的字体 HelveticaNeue Courier // 姓名字体,宏定义在Weibo.h UIFont *fnt = kNameFnt; // 根据字体得到NSString的尺寸 CGSize size = [_weibo.name sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:fnt,NSFontAttributeName, nil]]; // 名字的H CGFloat nameH = size.height; // 名字的W CGFloat nameW = size.width; _nameFrame = CGRectMake(nameX, nameY, nameW,nameH); // 4,正文的frame // x CGFloat contentX = _nameFrame.origin.x; // y CGFloat contentY = CGRectGetMaxY(_nameFrame) + kMargin; // CGFloat winWidth = [[UIApplication sharedApplication] statusBarFrame].size.width; // 宽度W CGFloat contentW = 320 - contentX - kMargin; CGRect tmpRect = [weibo.content boundingRectWithSize:CGSizeMake(contentW, 1000) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:kContentFnt,NSFontAttributeName, nil] context:nil]; // 高度H CGFloat contentH = tmpRect.size.height; _contentFrame = CGRectMake(contentX, contentY, contentW,contentH); // 5,bigImg的frame // x CGFloat bigImgX = _headImgFrame.origin.x; // y CGFloat extraSpace = weibo.isVIP?3:0; CGFloat bigImgY_1 = CGRectGetMaxY(_headImgFrame) + kMargin + extraSpace; CGFloat bigImgY_2 = CGRectGetMaxY(_contentFrame) + kMargin; CGFloat bigImgY = bigImgY_1>bigImgY_2?bigImgY_1:bigImgY_2; // 宽度W CGFloat bigImgW = 320 - kMargin*2; // 高度H CGFloat bigImgH = 320 - kMargin*2; _bigImgFrame = CGRectMake(bigImgX, bigImgY, bigImgW,bigImgH); // 6,发表的客户端client的frame // x CGFloat clientX = _bigImgFrame.origin.x; // y CGFloat clientY = CGRectGetMaxY(_bigImgFrame)+kMargin; // 根据字体得到NSString的尺寸 size = [weibo.client sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:kClientFnt,NSFontAttributeName, nil]]; // H CGFloat clientH = size.height; // W CGFloat clientW = size.width; _clientFrame = CGRectMake(clientX, clientY, clientW,clientH); // 7,发表时间postTime的frame // 发表时间,用的字体,宏定义在Weibo.h // 根据字体得到NSString的尺寸 size = [weibo.postTime sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:kPostTimeFnt,NSFontAttributeName, nil]]; // H CGFloat postTimeH = size.height; // W CGFloat postTimeW = size.width; // x CGFloat postTimeX = 320 - kMargin*2 - postTimeW; // y CGFloat postTimeY = CGRectGetMaxY(_nameFrame) - postTimeH; _postTimeFrame = CGRectMake(postTimeX, postTimeY, postTimeW,postTimeH); // 8,这个时候就可以计算最大Y 即行高了 _maxY = CGRectGetMaxY(_clientFrame) + kMargin; // 9,评论次数的frame 用的字体,宏定义在Weibo.h // 根据字体得到NSString的尺寸 NSLog(@"%@",weibo.commentNum); size = [weibo.commentNum sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:kCommentFnt,NSFontAttributeName, nil]]; // H CGFloat commentH = size.height; // W CGFloat commentW = size.width; // y CGFloat commentY = CGRectGetMaxY(_clientFrame) - commentH; // x CGFloat commentX = 320 - kMargin - commentW; _commentNumFrame = CGRectMake(commentX, commentY, commentW,commentH); // NSLog(@"评论数X--%f Y:%f----size:%f,%f",commentX,commentY,commentW,commentH); // 9,评论图片的frame // x CGFloat commentImgX = CGRectGetMinX(_commentNumFrame) - kMargin*0.5 - kCommentHW; // y CGFloat commentImgY = CGRectGetMaxY(_commentNumFrame) - kCommentHW; // H CGFloat commentImgH = kCommentHW; // W CGFloat commentImgW = kCommentHW; _commentImgFrame = CGRectMake(commentImgX, commentImgY, commentImgW, commentImgH); // 10,分享的frame 用的字体,宏定义在Weibo.h // 根据字体得到NSString的尺寸 size = [weibo.shareNum sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:kShareFnt,NSFontAttributeName, nil]]; // H CGFloat shareH = size.height; // W CGFloat shareW = size.width; // y CGFloat shareY = CGRectGetMaxY(_clientFrame) - shareH; // x CGFloat shareX = CGRectGetMinX(_commentImgFrame) - kMargin - shareW; _shareNumFrame = CGRectMake(shareX, shareY, shareW,shareH); // 11,分享图片的frame // x CGFloat shareImgX = CGRectGetMinX(_shareNumFrame) - kMargin*0.5 - kShareHW; // y CGFloat shareImgY = CGRectGetMaxY(_shareNumFrame) - kShareHW; // H CGFloat shareImgH = kShareHW; // W CGFloat shareImgW = kShareHW; _shareImgFrame = CGRectMake(shareImgX, shareImgY, shareImgW, shareImgH); // NSLog(@"shareImgX--%f Y:%f----size:%f,%f",shareImgX,shareImgY,shareImgW,shareImgH); } @end
WeiboCell.h
// // WeiboCell.h // 15_代码自定义cell_weibo // // Created by beyond on 14-7-29. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import <UIKit/UIKit.h> @class WeiboFrames; // 一行自定义的cell,初始化的时候,全部生成各个控件并添加到contentView,然后通过cellWithWeiboFrames方法,将参数weiboFrames(内含weibo对象)的所有成员frames和数据 设置到cell中的各个控件上面去 @interface WeiboCell : UITableViewCell // 返回xib界面上写的重用cellID + (NSString *)cellID; // 通过一个WeiboFrames模型对象(它本身就含有一个Weibo数据 模型),返回一个填充好数据的cell对象 - (WeiboCell *)cellWithWeiboFrames:(WeiboFrames *)weiboFrames; @end
WeiboCell.m
// // WeiboCell.m // 15_代码自定义cell_weibo // // Created by beyond on 14-7-29. // Copyright (c) 2014年 com.beyond. All rights reserved. // #import "WeiboCell.h" #import "Weibo.h" #import "WeiboFrames.h" // 类扩展,又叫匿名分类 @interface WeiboCell() { // 1,头像 UIImageView *_headImg; // 2,是不是大V UIImageView *_isVIP; // 3,名字 UILabel *_name; // 4,发表时间 UILabel *_postTime; // 5,正文内容 UILabel *_content; // 6,大图片 UIImageView *_bigImg; // 7,来自客户端 UILabel *_client; // 8,分享 UIImageView *_shareImg; // 9,评论 UIImageView *_commentImg; // 10,分享次数 UILabel *_shareNum; // 11,评论次数 UILabel *_commentNum; } @end @implementation WeiboCell // 返回xib界面上写的重用cellID + (NSString *)cellID { return @"Weibo"; } // 当池中没有WeiboCell的时候,创建出一个纯洁的WeiboCell,一次性alloc 出所有的各个子控件 ,并加到contentView - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // 不管三七二十一,先把所有的控件实例化,并添加到contentView里面 // 1,头像 _headImg = [[UIImageView alloc]init]; [self.contentView addSubview:_headImg]; // 2,是不是大V,并设置大V图片 _isVIP = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"大V"]]; [self.contentView addSubview:_isVIP]; // 3,名字 _name = [[UILabel alloc]init]; // 姓名字体,宏定义在Weibo.h _name.font = kNameFnt ; [self.contentView addSubview:_name]; // 4,发表时间 _postTime = [[UILabel alloc]init]; // 发表时间,用的字体,宏定义在Weibo.h _postTime.font = kPostTimeFnt; [self.contentView addSubview:_postTime]; // 5,正文内容 _content = [[UILabel alloc]init]; // 正文内容用的字体,宏定义在Weibo.h _content.font = kContentFnt; _content.numberOfLines = 0; _content.lineBreakMode = NSLineBreakByWordWrapping; [self.contentView addSubview:_content]; // 6,大图片 _bigImg = [[UIImageView alloc]init]; [self.contentView addSubview:_bigImg]; // 7,来自客户端,用的字体,宏定义在Weibo.h _client = [[UILabel alloc]init]; _client.font = kClientFnt; [_client setTextColor:[UIColor grayColor]]; [self.contentView addSubview:_client]; // 8,分享图片 _shareImg = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"share.png"]]; [self.contentView addSubview:_shareImg]; // 9,评论图片 _commentImg = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"comment.png"]]; [self.contentView addSubview:_commentImg]; // 10,分享次数 _shareNum = [[UILabel alloc]init]; _shareNum.font = kShareFnt; [_shareNum setTextColor:[UIColor darkGrayColor]]; [self.contentView addSubview:_shareNum]; // 12,评论次数 _commentNum = [[UILabel alloc]init]; _commentNum.font = kCommentFnt; [_commentNum setTextColor:[UIColor darkGrayColor]]; [self.contentView addSubview:_commentNum]; } return self; } // 通过一个WeiboFrames模型对象(它本身就含有一个Weibo数据 模型),返回一个填充好数据的cell对象,将参数weiboFrames(内含weibo对象)的所有成员frames和数据 设置到cell中的各个控件上面去 - (WeiboCell *)cellWithWeiboFrames:(WeiboFrames *)weiboFrames { // 将模型对象中的所有属性值,全部赋值到cell对象中的成员控件上显示 // 1,头像 _headImg.image = [UIImage imageNamed:weiboFrames.weibo.headImg]; // 2,是不是大V _isVIP.hidden = !weiboFrames.weibo.isVIP; if (_isVIP.hidden) { [_name setTextColor:[UIColor blackColor]]; } else { [_name setTextColor:[UIColor redColor]]; } // 3,名字 _name.text = weiboFrames.weibo.name; // 4,发表时间 _postTime.text = weiboFrames.weibo.postTime; // 5,正文内容 _content.text = weiboFrames.weibo.content; // 6,大图片 _bigImg.image = [UIImage imageNamed:weiboFrames.weibo.bigImg]; // 7,来自客户端 _client.text = weiboFrames.weibo.client; // 9,分享次数 _shareNum.text = weiboFrames.weibo.shareNum; // 11,评论次数 _commentNum.text = weiboFrames.weibo.commentNum; // 调用自定义方法,将参数weiboFrames的各个成员frames赋值给cell中各个成员控件 的frame [self calcFramesWithWeiboFrames:weiboFrames]; return self; } // 调用自定义方法,计算cell中各个成员控件 的frame - (void)calcFramesWithWeiboFrames:(WeiboFrames *)weiboFrames { // 1,头像的frame _headImg.frame = weiboFrames.headImgFrame; // 2,isVIP的frame _isVIP.frame = weiboFrames.isVIPFrame; // 3,名字的frame _name.frame = weiboFrames.nameFrame; // 4,正文的frame _content.frame = weiboFrames.contentFrame; // 5,bigImg的frame _bigImg.frame = weiboFrames.bigImgFrame; // 6,发表的客户端client的frame _client.frame = weiboFrames.clientFrame; // 7,发表时间postTime的frame _postTime.frame = weiboFrames.postTimeFrame; // 8,分享图片的frame _shareImg.frame = weiboFrames.shareImgFrame; // 9,分享次数的frame _shareNum.frame = weiboFrames.shareNumFrame; // 10,评论图片的frame _commentImg.frame = weiboFrames.commentImgFrame; // 11,评论次数的frame _commentNum.frame = weiboFrames.commentNumFrame; } @end
weibo.plist
微博蓝本截图: