终于效果图:
BeyondTableViewController.h
//// BeyondTableViewController.h// 15_代码自己定义cell_weibo//// Created by beyond on 14-7-29.// Copyright (c) 2014年 com.beyond. All rights reserved.//#import@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// 把要用到的字体抽成宏// 姓名 用的字体#define kNameFnt [UIFont fontWithName:@"HelveticaNeue" size:24.0f]// 内容 用的字体#define kContentFnt [UIFont fontWithName:@"HelveticaNeue" size:18.0f]// 来自client 用的字体#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;// 来自client@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@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@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
微博蓝本截图: