一、介绍
之前已经实现过通过简单的XIB文件来自定义我们的tableViewCell,包括每一步的步骤和代码:http://www.cnblogs.com/daomul/p/4355999.html
现在我们采取另外一种方式,通过纯编写代码来实现自定义我们的tableview,那么什么时候使用XIB,是这样的,当我们的cell的高度是固定的时候,我们可以采用XIB文件,如果我们的cell高度是不固定的,那么就需要使用代码编写了
二、效果
话不多说,上一个没有放图,这个先看我们大概做出来的效果如下:
三、 实现步骤
四、代码清单
ViewController.m:
1 // 2 // ViewController.m 3 // codeDefinedForTableviewcell 4 // 5 // Created by bos on 15-3-22. 6 // Copyright (c) 2015年 axiba. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "weiboCell.h" 11 #import "Weibo.h" 12 #import "WeiboFrame.h" 13 14 @interface ViewController () 15 { 16 //全局变量,对应着从文件中取得的数据 17 //NSMutableArray *_weibos; 18 NSMutableArray *_weiboFrames; 19 } 20 21 @end 22 23 @implementation ViewController 24 25 - (void)viewDidLoad { 26 [super viewDidLoad]; 27 28 //从plist文件中加载数据数组 29 NSArray *arr = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"data.plist" ofType:nil]]; 30 31 //遍历添加到我们的微博模型中 32 _weiboFrames = [NSMutableArray array]; 33 for (NSDictionary *dict in arr) { 34 WeiboFrame *wframe = [[WeiboFrame alloc]init]; 35 wframe.weibo = [Weibo weiboWithDict:dict]; 36 37 [_weiboFrames addObject:wframe]; 38 } 39 /*_weibos = [NSMutableArray array]; 40 for (NSDictionary *key in arr) { 41 42 //每一个可变数组中存放每条模型(多少条就是对应着多少行 ) 43 [_weibos addObject:[Weibo weiboWithDict:key]]; 44 }*/ 45 } 46 47 - (void)didReceiveMemoryWarning { 48 [super didReceiveMemoryWarning]; 49 // Dispose of any resources that can be recreated. 50 } 51 52 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 53 { 54 return _weiboFrames.count; 55 } 56 57 -(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 58 { 59 //1、去缓存池取出cell 60 weiboCell *cell = [tableView dequeueReusableCellWithIdentifier:[weiboCell getID]]; 61 62 //2、如果不存在缓存,则创建一个 63 if (cell ==nil) { 64 cell = [[weiboCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[weiboCell getID]]; 65 } 66 67 //3、传递模型数据(相当于setWeibo,没有传递则) 68 //WeiboFrame *wframe = [[WeiboFrame alloc] init]; 69 //wframe.weibo = _weiboFrames[indexPath.row]; 70 cell.weiboframe = _weiboFrames[indexPath.row]; 71 72 return cell; 73 } 74 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 75 { 76 //WeiboFrame *wframe = [[WeiboFrame alloc] init]; 77 //wframe.weibo = _weibofr[indexPath.row]; 78 //return wframe.cellHeight; 79 80 return [_weiboFrames[indexPath.row] cellHeight]; 81 } 82 83 @end
WeiboCell.h
1 // 2 // weiboCell.h 3 // codeDefinedForTableviewcell 4 // 5 // Created by bos on 15-3-22. 6 // Copyright (c) 2015年 axiba. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 @class WeiboFrame; 11 12 @interface weiboCell : UITableViewCell 13 14 @property (nonatomic,strong) UILabel *iconlabel; 15 @property (nonatomic,strong) UILabel *namelabel; 16 @property (nonatomic ,strong) UILabel *timelabel; 17 @property (nonatomic,strong) UIImageView *vipImage; 18 @property (nonatomic,strong) UIImageView *picImage; 19 @property (nonatomic,strong) UILabel *contentLabel; 20 @property (nonatomic,strong) UILabel *from; 21 22 @property (nonatomic,strong) WeiboFrame *weiboframe; 23 24 +(NSString *)getID; 25 @end
WeiboCell.m
1 // 2 // weiboCell.m 模型显示到我们的cell里面 3 // codeDefinedForTableviewcell 4 // 5 // Created by bos on 15-3-22. 6 // Copyright (c) 2015年 axiba. All rights reserved. 7 // 8 9 #import "weiboCell.h" 10 #import "Weibo.h" 11 #import "WeiboFrame.h" 12 13 #define kCellBorder 10 14 #define kIconWH 40 15 16 @interface weiboCell() 17 { 18 UIImageView *_icon; 19 UILabel *_name; 20 UILabel *_content; 21 UIImageView *_vip; 22 UIImageView *_pic; 23 UILabel *_from; 24 UILabel *_time; 25 } 26 27 @end 28 29 @implementation weiboCell 30 31 -(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 32 { 33 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 34 if (self) { 35 36 //不清楚高度则先添加基本得内部所有子控件 37 [self setData]; 38 } 39 40 return self; 41 } 42 43 #pragma 设置微博数据以及高度frame 44 -(void)setWeiboframe:(WeiboFrame *)weiboframe 45 { 46 //1.将weibo负值给我们的weibo模型 47 _weiboframe = weiboframe; 48 49 //2.设置微博数据 50 [self settingWeiboData]; 51 52 //3.设置子控件的frame 53 [self settingWeiboFrame]; 54 } 55 #pragma 设置微博数据 56 -(void)settingWeiboData 57 { 58 Weibo *weibo = _weiboframe.weibo; 59 //赋值 60 _icon.image = [UIImage imageNamed:weibo.icon]; 61 62 _name.text = weibo.name; 63 64 _content.text = weibo.content; 65 _content.numberOfLines = 0; 66 67 _from.text = weibo.from; 68 69 _vip.hidden = !weibo.vip; 70 71 _time.text = weibo.time; 72 73 // 配图 74 if (weibo.pic) { 75 _pic.hidden = NO; 76 _pic.image = [UIImage imageNamed:weibo.pic]; 77 }else 78 { 79 _pic.hidden = YES; 80 } 81 82 } 83 #pragma 设置微博高度frame 84 -(void) settingWeiboFrame 85 { 86 87 //1、头像 88 _icon.frame = _weiboframe.iconFrame; 89 90 //2、昵称 91 _name.frame = _weiboframe.nameFrame; 92 93 //3VIP图标 94 _vip.frame = _weiboframe.vipFrame; 95 96 //4、时间 97 _time.frame = _weiboframe.timeFrame; 98 99 //5来源 100 _from.frame = _weiboframe.fromFrame; 101 102 //6正文 103 _content.frame = _weiboframe.contentFrame; 104 105 106 //7配图 107 if (_weiboframe.weibo.pic) { 108 109 _pic.frame = _weiboframe.picFrame; 110 } 111 } 112 113 114 115 #pragma 添加基本的内部控件 116 -(void)setData 117 { 118 //1、头像 119 _icon = [[UIImageView alloc] init]; 120 [self.contentView addSubview:_icon]; 121 122 //2、会员姓名 123 _name = [[UILabel alloc] init]; 124 [self.contentView addSubview: _name]; 125 126 //3、时间 127 _time = [[UILabel alloc] init]; 128 _time.font = [UIFont systemFontOfSize:12]; 129 [self.contentView addSubview:_time]; 130 131 //4、正文 132 _content= [[UILabel alloc] init]; 133 [self.contentView addSubview:_content]; 134 135 //5、VIP图标 136 _vip = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"vip.png"]]; 137 [self.contentView addSubview:_vip]; 138 139 //6、微博配图 140 _pic= [[UIImageView alloc] init]; 141 [self.contentView addSubview:_pic]; 142 143 //7、来源 144 _from = [[UILabel alloc] init]; 145 _from.font = _time.font; 146 [self.contentView addSubview:_from]; 147 148 149 } 150 151 +(NSString *)getID 152 { 153 return @"cell"; 154 } 155 156 157 @end
Weibo.h
1 // 2 // Weibo.h 3 // codeDefinedForTableviewcell 4 // 5 // Created by bos on 15-3-22. 6 // Copyright (c) 2015年 axiba. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 @interface Weibo : NSObject 12 13 @property (nonatomic,copy) NSString *name; 14 @property (nonatomic,copy) NSString *icon; 15 @property (nonatomic,copy) NSString *time; 16 @property (nonatomic, copy) NSString *pic; 17 @property (nonatomic,copy) NSString *content; 18 @property (nonatomic,copy) NSString *from; 19 @property (nonatomic,assign) BOOL vip; 20 21 -(id) initWithDict:(NSDictionary *)dict; 22 +(id) weiboWithDict:(NSDictionary *)dict; 23 24 @end
Weibo.m
1 // 2 // Weibo.m 模型 3 // codeDefinedForTableviewcell 4 // 5 // Created by bos on 15-3-22. 6 // Copyright (c) 2015年 axiba. All rights reserved. 7 // 8 9 #import "Weibo.h" 10 11 @implementation Weibo 12 13 -(id) initWithDict:(NSDictionary *)dict 14 { 15 if (self == [super init]) { 16 self.name =dict[@"name"]; 17 self.icon = dict[@"icon"]; 18 self.time = dict[@"time"]; 19 self.content = dict[@"desc"]; 20 self.from = dict[@"from"]; 21 self.pic = dict[@"pic"]; 22 self.vip = [dict[@"vip"] boolValue]; 23 } 24 return self; 25 } 26 27 //必须实现的类方法,否则类无法alloc 自己(self) 28 +(id) weiboWithDict:(NSDictionary *)dict 29 { 30 return [[self alloc] initWithDict:dict]; 31 } 32 33 @end
WeiboFrame.h
1 // 2 // WeiboFrame.h 3 // codeDefinedForTableviewcell 4 // 5 // Created by bos on 15-4-8. 6 // Copyright (c) 2015年 axiba. All rights reserved. 7 // 用来存放某一个cell内部所有的子控件 的frame 8 9 #import <Foundation/Foundation.h> 10 #import <UIKit/UIKit.h> 11 12 @class Weibo; 13 @interface WeiboFrame : NSObject 14 15 16 // 头像 的frame 17 @property (nonatomic,assign,readonly) CGRect iconFrame; 18 // 是不是大V 的frame 19 @property (nonatomic,assign,readonly) CGRect vipFrame; 20 // 名字 的frame 21 @property (nonatomic,assign,readonly) CGRect nameFrame; 22 // 发表时间 的frame 23 @property (nonatomic,assign,readonly) CGRect timeFrame; 24 // 正文内容 的frame 25 @property (nonatomic,assign,readonly) CGRect contentFrame; 26 // 大图片 的frame 27 @property (nonatomic,assign,readonly) CGRect picFrame; 28 // 来自客户端 的frame 29 @property (nonatomic,assign,readonly) CGRect fromFrame; 30 31 @property (nonatomic,assign,readonly) CGFloat cellHeight; 32 @property (nonatomic,strong) Weibo *weibo; 33 34 @end
WeiboFram.m
1 // 2 // WeiboFrame.m 3 // codeDefinedForTableviewcell 4 // 5 // Created by bos on 15-4-8. 6 // Copyright (c) 2015年 axiba. All rights reserved. 7 // yonglai 8 9 10 #define kCellBorder 10 11 #define kIconWH 40 12 13 #import "WeiboFrame.h" 14 #import "Weibo.h" 15 16 @implementation WeiboFrame 17 18 -(void) setWeibo:(Weibo *)weibo 19 { 20 _weibo = weibo; 21 22 23 //1、头像 24 CGFloat iconX = kCellBorder; 25 CGFloat iconY = kCellBorder; 26 _iconFrame = CGRectMake(iconX, iconY, kIconWH, kIconWH); 27 28 //2、昵称 29 CGFloat nameX = CGRectGetMaxX(_iconFrame) + kCellBorder; 30 CGFloat nameY = iconY; 31 //宽高取决于文字宽度 32 CGSize nameSize = [self getLabelHeighDynamic:_weibo.name]; 33 _nameFrame = CGRectMake(nameX, nameY, nameSize.width, nameSize.height); 34 35 //3VIP图标 36 37 CGFloat vipX = CGRectGetMaxX(_nameFrame) + kCellBorder; 38 CGFloat vipY = nameY; 39 _vipFrame = CGRectMake(vipX, vipY, 20, 20); 40 41 //4、时间 42 CGFloat timeX = nameX; 43 CGFloat timeY = CGRectGetMaxY(_nameFrame) + kCellBorder; 44 CGSize timeSize = [self getLabelHeighDynamic:_weibo.time]; 45 _timeFrame = CGRectMake(timeX, timeY, timeSize.width, timeSize.height); 46 47 //5来源 48 CGFloat fromX = CGRectGetMaxX(_timeFrame) +kCellBorder; 49 CGFloat fromY = timeY; 50 CGSize fromSize = [self getLabelHeighDynamic: _weibo.from]; 51 _fromFrame = CGRectMake(fromX, fromY, fromSize.width, fromSize.height); 52 53 //6正文 54 CGFloat contentX = iconX; 55 CGFloat contentY = MAX(CGRectGetMaxY(_iconFrame), CGRectGetMaxY(_timeFrame)); 56 CGRect contentSize = [self getContentFrameDynamic: _weibo.content]; 57 _contentFrame = CGRectMake(contentX, contentY, contentSize.size.width, contentSize.size.height); 58 59 60 //7配图 61 if (_weibo.pic.length > 0) { 62 63 CGFloat picX = contentX; 64 CGFloat picY = CGRectGetMaxY(_contentFrame) +kCellBorder; 65 _picFrame = CGRectMake(picX, picY, 80, 80); 66 67 _cellHeight = CGRectGetMaxY(_picFrame) + kCellBorder; 68 } 69 else 70 { 71 _cellHeight = CGRectGetMaxY(_contentFrame) +kCellBorder; 72 } 73 } 74 75 #pragma 根据文字长度动态确定label的高度 76 -(CGSize)getLabelHeighDynamic:(NSString *)word 77 { 78 UIFont *fnt = [UIFont fontWithName:@"HelveticaNeue" size:18.0f]; 79 CGSize size = [word sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:fnt,NSFontAttributeName, nil]]; 80 return size; 81 } 82 83 #pragma 根据正文内容多少,动态确定正文content的frame 84 85 -(CGRect)getContentFrameDynamic:(NSString *)word 86 { 87 // 宽度W 88 CGFloat contentW = 320 - 2 *kCellBorder; 89 // label的字体 HelveticaNeue Courier 90 UIFont *fnt = [UIFont fontWithName:@"HelveticaNeue" size:18.0f]; 91 //_content.font = fnt; 92 93 //_content.lineBreakMode = NSLineBreakByWordWrapping; 94 // iOS7中用以下方法替代过时的iOS6中的sizeWithFont:constrainedToSize:lineBreakMode:方法 95 CGRect tmpRect = [word boundingRectWithSize:CGSizeMake(contentW, 1000) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:fnt,NSFontAttributeName, nil] context:nil]; 96 97 return tmpRect; 98 99 } 100 101 102 @end
五、遇到的问题总结
1、number函数写错, 记得是tableview先写,否则导致无法执行cellforRowAtIndexpath无法执行
2、忘记传递模型数据,导致set方法没有执行
3、IOS7中用以下方法
- (CGSize)sizeWithAttributes:(NSDictionary *)attrs;
替代过时的iOS6中的- (CGSize)sizeWithFont:(UIFont *)font 方法
4、如果头文件中遇到类似于“编绎显示Unknown type name “CGFloat” 错误解决方法”
直接加头文件:
#import <UIKit/UIKit.h>或者将Compile Sources As 改为 Objective-C++
5、在ViewDidLoad使用以下方法在取缓存池的值的时候,可以不用判断是否为空,会自动取缓冲取值,适用于6.0+
[self.tableView registerClass:[Mycell class] forCellReuseIdenifier:@"cellID"];
六、源代码下载地址:
http://pan.baidu.com/s/1kTqsTpH