代码实现cell 的定制
[以下代码均来自网络 这里只是整理]
代码实现遵循MVC设计思路,这里体现的是一个设计的基本思路和封装过程,代理实现

封装基本思路:
开发步骤:
1.新建一个继承自UITableViewCell的类
2.重写initWithStyle:reuseIdentifier:方法
添加所有需要显示的子控件(不需要设置子控件的数据和frame, 子控件要添加到contentView中)
进行子控件一次性的属性设置(有些属性只需要设置一次, 比如字体\固定的图片)
3.提供2个模型
数据模型: 存放文字数据\图片数据
frame模型: 存放数据模型\所有子控件的frame\cell的高度
4.cell拥有一个frame模型(不要直接拥有数据模型)
5.重写frame模型属性的setter方法: 在这个方法中设置子控件的显示数据和frame
6.frame模型数据的初始化已经采取懒加载的方式(每一个cell对应的frame模型数据只加载一次)
一: view文件夹:.h文件
1 #import <UIKit/UIKit.h> 2 @class MJStatusFrame; 3 4 @interface MJStatusCell : UITableViewCell 5 @property (nonatomic, strong) MJStatusFrame *statusFrame; 6 7 + (instancetype)cellWithTableView:(UITableView *)tableView; 8 @end
.m文件
1 // 昵称的字体 2 #define MJNameFont [UIFont systemFontOfSize:14] 3 // 正文的字体 4 #define MJTextFont [UIFont systemFontOfSize:15] 5 6 #import "MJStatusCell.h" 7 #import "MJStatus.h" 8 #import "MJStatusFrame.h" 9 10 @interface MJStatusCell() 11 /** 12 * 头像 13 */ 14 @property (nonatomic, weak) UIImageView *iconView; 15 /** 16 * 昵称 17 */ 18 @property (nonatomic, weak) UILabel *nameView; 19 /** 20 * 会员图标 21 */ 22 @property (nonatomic, weak) UIImageView *vipView; 23 /** 24 * 正文 25 */ 26 @property (nonatomic, weak) UILabel *textView; 27 /** 28 * 配图 29 */ 30 @property (nonatomic, weak) UIImageView *pictureView; 31 @end 32 33 @implementation MJStatusCell 34 35 /** 36 * 构造方法(在初始化对象的时候会调用) 37 * 一般在这个方法中添加需要显示的子控件 38 */ 39 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 40 { 41 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 42 if (self) { 43 // 1.头像 44 UIImageView *iconView = [[UIImageView alloc] init]; 45 [self.contentView addSubview:iconView]; 46 self.iconView = iconView; 47 48 // 2.昵称 49 UILabel *nameView = [[UILabel alloc] init]; 50 nameView.font = MJNameFont; 51 [self.contentView addSubview:nameView]; 52 self.nameView = nameView; 53 54 // 3.会员图标 55 UIImageView *vipView = [[UIImageView alloc] init]; 56 vipView.image = [UIImage imageNamed:@"vip"]; 57 [self.contentView addSubview:vipView]; 58 self.vipView = vipView; 59 60 // 4.正文 61 UILabel *textView = [[UILabel alloc] init]; 62 textView.numberOfLines = 0; 63 textView.font = MJTextFont; 64 [self.contentView addSubview:textView]; 65 self.textView = textView; 66 67 // 5.配图 68 UIImageView *pictureView = [[UIImageView alloc] init]; 69 [self.contentView addSubview:pictureView]; 70 self.pictureView = pictureView; 71 } 72 return self; 73 } 74 75 /** 76 * 在这个方法中设置子控件的frame和显示数据 77 */ 78 - (void)setStatusFrame:(MJStatusFrame *)statusFrame 79 { 80 _statusFrame = statusFrame; 81 82 // 1.设置数据 83 [self settingData]; 84 85 // 2.设置frame 86 [self settingFrame]; 87 } 88 89 /** 90 * 设置数据 91 */ 92 - (void)settingData 93 { 94 // 微博数据 95 MJStatus *status = self.statusFrame.status; 96 97 // 1.头像 98 self.iconView.image = [UIImage imageNamed:status.icon]; 99 100 // 2.昵称 101 self.nameView.text = status.name; 102 103 // 3.会员图标 104 if (status.vip) { 105 self.vipView.hidden = NO; 106 107 self.nameView.textColor = [UIColor redColor]; 108 } else { 109 self.vipView.hidden = YES; 110 111 self.nameView.textColor = [UIColor blackColor]; 112 } 113 114 // 4.正文 115 self.textView.text = status.text; 116 117 // 5.配图 118 if (status.picture) { // 有配图 119 self.pictureView.hidden = NO; 120 self.pictureView.image = [UIImage imageNamed:status.picture]; 121 } else { // 没有配图 122 self.pictureView.hidden = YES; 123 } 124 } 125 126 /** 127 * 计算文字尺寸 128 * 129 * @param text 需要计算尺寸的文字 130 * @param font 文字的字体 131 * @param maxSize 文字的最大尺寸 132 */ 133 - (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize 134 { 135 NSDictionary *attrs = @{NSFontAttributeName : font}; 136 return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size; 137 } 138 139 /** 140 * 设置frame 141 */ 142 - (void)settingFrame 143 { 144 // 1.头像 145 self.iconView.frame = self.statusFrame.iconF; 146 147 // 2.昵称 148 self.nameView.frame = self.statusFrame.nameF; 149 150 // 3.会员图标 151 self.vipView.frame = self.statusFrame.vipF; 152 153 // 4.正文 154 self.textView.frame = self.statusFrame.textF; 155 156 // 5.配图 157 if (self.statusFrame.status.picture) {// 有配图 158 self.pictureView.frame = self.statusFrame.pictureF; 159 } 160 } 161 162 + (instancetype)cellWithTableView:(UITableView *)tableView 163 { 164 static NSString *ID = @"status"; 165 MJStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; 166 if (cell == nil) { 167 cell = [[MJStatusCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 168 } 169 return cell; 170 } 171 @end
二:Modle 文件夹文件 .h文件是针对自定义cell
mjStatus.h
1 #import <Foundation/Foundation.h> 2 3 @interface MJStatus : NSObject 4 @property (nonatomic, copy) NSString *text; // 内容 5 @property (nonatomic, copy) NSString *icon; // 头像 6 @property (nonatomic, copy) NSString *name; // 昵称 7 @property (nonatomic, copy) NSString *picture; // 配图 8 @property (nonatomic, assign) BOOL vip; 9 10 - (instancetype)initWithDict:(NSDictionary *)dict; 11 + (instancetype)statusWithDict:(NSDictionary *)dict; 12 @end
MJstatus.m 这里是实现cellmodel 的单例实现
1 #import "MJStatus.h" 2 3 @implementation MJStatus 4 5 - (instancetype)initWithDict:(NSDictionary *)dict 6 { 7 if (self = [super init]) { 8 [self setValuesForKeysWithDictionary:dict]; 9 } 10 return self; 11 } 12 13 + (instancetype)statusWithDict:(NSDictionary *)dict 14 { 15 return [[self alloc] initWithDict:dict]; 16 } 17 18 @end
对一个基model 进行封装 用于实现对自定义cell的frame计算
MjstatusFrame.h
1 // 2 // MJStatusFrame.h 3 // 04-微博 4 // 5 // Created by apple on 14-4-1. 6 // Copyright (c) 2014年 itcast. All rights reserved. 7 // 这个模型对象专门用来存放cell内部所有的子控件的frame数据 + cell的高度 8 // 一个cell拥有一个MJStatusFrame模型 9 10 #import <Foundation/Foundation.h> 11 12 @class MJStatus; 13 14 @interface MJStatusFrame : NSObject 15 /** 16 * 头像的frame 17 */ 18 @property (nonatomic, assign, readonly) CGRect iconF; 19 /** 20 * 昵称的frame 21 */ 22 @property (nonatomic, assign, readonly) CGRect nameF; 23 /** 24 * 会员图标的frame 25 */ 26 @property (nonatomic, assign, readonly) CGRect vipF; 27 /** 28 * 正文的frame 29 */ 30 @property (nonatomic, assign, readonly) CGRect textF; 31 /** 32 * 配图的frame 33 */ 34 @property (nonatomic, assign, readonly) CGRect pictureF; 35 36 /** 37 * cell的高度 38 */ 39 @property (nonatomic, assign, readonly) CGFloat cellHeight; 40 41 @property (nonatomic, strong) MJStatus *status; 42 @end
MjstatusFrame.M
1 // 2 // MJStatusFrame.m 3 // 04-微博 4 // 5 // Created by apple on 14-4-1. 6 // Copyright (c) 2014年 itcast. All rights reserved. 7 // 8 9 // 昵称的字体 10 #define MJNameFont [UIFont systemFontOfSize:14] 11 // 正文的字体 12 #define MJTextFont [UIFont systemFontOfSize:15] 13 14 #import "MJStatusFrame.h" 15 #import "MJStatus.h" 16 17 @implementation MJStatusFrame 18 19 /** 20 * 计算文字尺寸 21 * 22 * @param text 需要计算尺寸的文字 23 * @param font 文字的字体 24 * @param maxSize 文字的最大尺寸 25 */ 26 - (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize 27 { 28 NSDictionary *attrs = @{NSFontAttributeName : font}; 29 return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size; 30 } 31 32 33 - (void)setStatus:(MJStatus *)status 34 { 35 _status = status; 36 37 // 子控件之间的间距 38 CGFloat padding = 10; 39 40 // 1.头像 41 CGFloat iconX = padding; 42 CGFloat iconY = padding; 43 CGFloat iconW = 30; 44 CGFloat iconH = 30; 45 _iconF = CGRectMake(iconX, iconY, iconW, iconH); 46 47 // 2.昵称 48 // 文字的字体 49 CGSize nameSize = [self sizeWithText:self.status.name font:MJNameFont maxSize:CGSizeMake(MAXFLOAT, MAXFLOAT)]; 50 CGFloat nameX = CGRectGetMaxX(_iconF) + padding; 51 CGFloat nameY = iconY + (iconH - nameSize.height) * 0.5; 52 _nameF = CGRectMake(nameX, nameY, nameSize.width, nameSize.height); 53 54 // 3.会员图标 55 CGFloat vipX = CGRectGetMaxX(_nameF) + padding; 56 CGFloat vipY = nameY; 57 CGFloat vipW = 14; 58 CGFloat vipH = 14; 59 _vipF = CGRectMake(vipX, vipY, vipW, vipH); 60 61 // 4.正文 62 CGFloat textX = iconX; 63 CGFloat textY = CGRectGetMaxY(_iconF) + padding; 64 CGSize textSize = [self sizeWithText:self.status.text font:MJTextFont maxSize:CGSizeMake(300, MAXFLOAT)]; 65 _textF = CGRectMake(textX, textY, textSize.width, textSize.height); 66 67 // 5.配图 68 if (self.status.picture) {// 有配图 69 CGFloat pictureX = textX; 70 CGFloat pictureY = CGRectGetMaxY(_textF) + padding; 71 CGFloat pictureW = 100; 72 CGFloat pictureH = 100; 73 _pictureF = CGRectMake(pictureX, pictureY, pictureW, pictureH); 74 75 _cellHeight = CGRectGetMaxY(_pictureF) + padding; 76 } else { 77 _cellHeight = CGRectGetMaxY(_textF) + padding; 78 } 79 } 80 @end
三:Controller文件夹 内部文件实现:
封装的思想就是尽可能让控制器做更少的事情,让控制器知道的越少越好,而其内部子模块则尽可能封装自己的功能 对于只是通过简单的借口实现自身初始化
而有关控件本身功能则尽量在封装的自身模块实现
控制器代码MJViewController.h
1 // 2 // MJViewController.h 3 // 04-微博 4 // 5 // Created by apple o 6 // Copyright (c) 2014年 itcast. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h> 10 11 @interface MJViewController : UITableViewController 12 13 @end
MJViewContorller.m
这里实现 了控制器的全部功能,包括与cell 实现时候对cell 状态的鉴定 【代理实现过程】
1 // 2 // MJViewController.m 3 // 04-微博 4 // 5 // Created by apple on 14-4-1. 6 // Copyright (c) 2014年 itcast. All rights reserved. 7 // 8 9 #import "MJViewController.h" 10 #import "MJStatus.h" 11 #import "MJStatusFrame.h" 12 #import "MJStatusCell.h" 13 14 @interface MJViewController () 15 //@property (nonatomic, strong) NSArray *statuses; 16 /** 17 * 存放所有cell的frame模型数据 18 */ 19 @property (nonatomic, strong) NSArray *statusFrames; 20 @end 21 22 @implementation MJViewController 23 24 - (void)viewDidLoad 25 { 26 [super viewDidLoad]; 27 28 // self.tableView.rowHeight = 400; 29 } 30 31 - (NSArray *)statusFrames 32 { 33 if (_statusFrames == nil) { 34 // 初始化 35 // 1.获得plist的全路径 36 NSString *path = [[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil]; 37 38 // 2.加载数组 39 NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; 40 41 // 3.将dictArray里面的所有字典转成模型对象,放到新的数组中 42 NSMutableArray *statusFrameArray = [NSMutableArray array]; 43 for (NSDictionary *dict in dictArray) { 44 // 3.1.创建MJStatus模型对象 45 MJStatus *status = [MJStatus statusWithDict:dict]; 46 47 // 3.2.创建MJStatusFrame模型对象 48 MJStatusFrame *statusFrame = [[MJStatusFrame alloc] init]; 49 statusFrame.status = status; 50 51 // 3.2.添加模型对象到数组中 52 [statusFrameArray addObject:statusFrame]; 53 } 54 55 // 4.赋值 56 _statusFrames = statusFrameArray; 57 } 58 return _statusFrames; 59 } 60 61 - (BOOL)prefersStatusBarHidden 62 { 63 return YES; 64 } 65 66 #pragma mark - 实现数据源方法 67 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 68 { 69 return self.statusFrames.count; 70 } 71 72 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 73 { 74 // 1.创建cell 75 MJStatusCell *cell = [MJStatusCell cellWithTableView:tableView]; 76 77 // 2.在这个方法算好了cell的高度 78 cell.statusFrame = self.statusFrames[indexPath.row]; 79 80 // 3.返回cell 81 return cell; 82 } 83 84 #pragma mark - 实现代理方法 85 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 86 { 87 // 取出这行对应的frame模型 88 MJStatusFrame *statusFrame = self.statusFrames[indexPath.row]; 89 return statusFrame.cellHeight; 90 } 91 92 @end

浙公网安备 33010602011771号