代码实现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
View Code

对一个基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
View Code

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
View Code

三: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
View Code

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
View Code

 

posted @ 2015-09-06 10:36  Caolongs  阅读(323)  评论(0)    收藏  举报