一、介紹
之前已經實現過通過簡單的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
