最终效果图:
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
微博蓝本截图: