tableView中自定义cell的高度随子控件的内容动态变化,也是用的非常多的地方。现在就来处理一个自定义一个里面有文字(多少不定),图片(有无不定)的cell
首先要准备两个模型,一个是存放数据的模型,另一个计算cell高度的模型。
具体代码分析如下:(红色为关键代码)
7 在ViewController.m中
8 //懒加载
9 -(NSArray *)allmodel{
10
11 if (_allmodel==nil)
12
13 {
14
15 NSString *path = [[NSBundle mainBundle]pathForResource:@"model.plist" ofType:nil];
16
17 NSArray *arry = [NSArray arrayWithContentsOfFile:path];
18
19 NSMutableArray *arry = [NSMutableArray array];
20
21 for (NSDictionary *dic in arry) {
22
23
24
25 Model *model = [Modelstaue modelWithstaue:dic];
26
27 ModelFrame *modelframe = [[ModelFrame alloc]init];
28
29 modelframe.Fmodel = model;
30
31 [allist addObject:modelframe];
32
33 }
34
35 _allmodel = arry;
36
37 }
38
39 return _allmodel;
40
41 }
42
43 其他的代码,暂时不管
44
45 开始计算。。。
46
47 在计算cell高度的模型中ModelF中
48
49 ModelFra.h中
50
51 @class Modelstaue;
52
53 @interface ModelFrame : NSObject
54
55 //CGRect 后面可不要不小心入了*这个哦
56
57 头像的frame
58
59 @property (nonatomic, assign, readonly) CGRect touF;
60
61
62
63 昵称的frame
64
65 @property (nonatomic, assign, readonly) CGRect nameF;
66
67
68
69 会员图标的frame
70
71 @property (nonatomic, assign, readonly) CGRect vipF;
72
73
74
75 正文的frame
76
77 @property (nonatomic, assign, readonly) CGRect textF;
78
79
80
81 图片的frame
82
83 @property (nonatomic, assign, readonly) CGRect pictureF;
84
85
86
87 cell的高度
88
89 @property (nonatomic, assign, readonly) float cellHeight;
90
91 @property(nonatomic,strong)Modelstaue *modelF;
92
93
94
95 在#import "modelFra.h",也就是.m文件中
96
97 #define NameFont [UIFont systemFontOfSize:14]
98
99 // 正文的字体
100
101 #define TextFont [UIFont systemFontOfSize:15]
102
103
104
105 @implementation ModelFra
106
107 -(void)setModelF:(Modelstaue *)modelF{
108
109 _modelF = modelF;
110
111 // 1.头像
112
113 _touF = CGRectMake(10,10,30,30);
114
115 // 2.昵称
116
117 CGSize nameSize = [self sizeWithText:self.status.name font:MJNameFont maxSize:CGSizeMake(MAXFLOAT, MAXFLOAT)];//先计算出宽高,后面方便算出坐标 MAXFLOAT-最大值
118
119 CGFloat nameX = CGRectGetMaxX(_touF) + 10;
120
121 CGFloat nameY = 10 + (30 - nameSize.height) /2;//让昵称保持在右边中间
122
123 _nameF = CGRectMake(nameX, nameY, nameSize.width, nameSize.height);
124
125
126
127 // 3.会员图标
128
129 _vipF = CGRectMake(CGRectGetMaxX(_nameF) + 10, nameY, 15, 14);
130
131
132
133 // 4.正文
134
135 CGFloat textX = iconX;
136
137 CGFloat textY = CGRectGetMaxY(_iconF) + padding;
138
139 CGSize textSize = [self sizeWithText:self.status.text font:TextFont maxSize:CGSizeMake(300, MAXFLOAT)];//这里就不用在写成了MAXFLOAT,正文会超出屏幕的宽
140
141 _textF = CGRectMake(10, CGRectGetMaxY(_touF) + 10, textSize.width, textSize.height);
142
143
144
145 // 5.图
146
147 if (self.modelF.picture) {
148
149 // 图
150
151 _pictureF = CGRectMake(10,CGRectGetMaxY(_textF) + 10, 100, 100);
152
153 //根据所以的子控件的高度,从而得到了cell的高度
154
155 _cellHeight = CGRectGetMaxY(_pictureF) + 10;
156
157 } else {
158
159 _cellHeight = CGRectGetMaxY(_textF) + 10;//无图的话
160
161 }
162
163 }
164
165
166
167 //根据文字的大小和尺寸来确定宽高的公式(封装了计算方法)
168
169 - (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize
170
171 {
172
173 NSDictionary *attrs = @{NSFontAttributeName : font};
174
175 return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size;
176
177 }
1 #import "WTableViewCell.h"//在cell的.m文件里
2 #import "ModelFra.h"
3 #import "Model.h"
4 @interface WTableViewCell()
5 @property (nonatomic, retain) UIImageView *touView;
6 /**
7 * 昵称
8 */
9 @property (nonatomic, retain) UILabel *nameView;
10 /**
11 * 会员
12 */
13 @property (nonatomic, retain) UIImageView *vipView;
14 /**
15 * 正文
16 */
17 @property (nonatomic, retain) UILabel *textView;
18 /**
19 * 图
20 */
21 @property (nonatomic, retain) UIImageView *pictureView;
22 @end
23
24 @implementation WTableViewCell
25
26
27 -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
28
29 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
30
31 if (self) {
32
33 // 头像
34 self.touView = [[UIImageView alloc]init];
35
36 [self.contentView addSubview:self.touView];
37
38 // 昵称
39 self.nameView = [[UILabel alloc]init];
40 self.nameView.font = [UIFont systemFontOfSize:14];
41 self.nameView.numberOfLines = 0;
42 ****千万不要忘记给定字体大小了,不要会出现比如导致出现了label上的文字和背景分离的奇怪现象,这是血的教训
44 [self.contentView addSubview:self.nameView];
45 // 图标
46 self.vipView = [[UIImageView alloc]init];
47 [self.contentView addSubview:self.vipView];
48 // 内容
49 self.textView = [[UILabel alloc]init];
50 self.textView.font = [UIFont systemFontOfSize:15];
51 、、不要以为计算模型那里已经赋值,两个概念,完全不一样,现在要给定大小装进计算好的模型里面去
52 self.textView.numberOfLines = 0;
53 [self.contentView addSubview:self.textView];
54 // 配图
55 self.pictureView = [[UIImageView alloc]init];
56 [self.contentView addSubview:self.pictureView];
57
58
59 }
60 return self;
61 }
62
63
64 -(void)setModelF:(ModelFrame *)modelF{
65 _modelF = modelF;
66 // 数据(当然也不是非得把数据放到这里,只是这样可以减少vc里面的代码)
67 [self setingData] ;
68 // 计算高度(为什么用到另外一个模型来计算呢?因为在自定义cell里面计算的话,cell的高度无法传出去)
69 [self setingFrame];
70
71 }
72
73 //传入模型数据
74 -(void)setingData{
75 Model *model = self.modelframe.status;
76 self.touView.image = [UIImage imageNamed:model.tou];
77 self.textView.text = model.text;
78
79 self.nameView.text = model.name;
下面的判断就可以做出有图片和有无会员图标的啦,要是把数据放在vc那里的话 到这里就相当麻烦了
80 if (model.picture) {//这里要作判断
81 self.pictureView.hidden = NO;//如果有图片 那就不要隐藏
82 self.pictureView.image = [UIImage imageNamed:model.picture];
83 }else{
84 self.pictureView.hidden = YES;//没有图片的话 就隐藏
85 }
86
87 if (model.vip) {
88 self.vipView.hidden = 0;
89 self.nameView.textColor = [UIColor redColor];
90 }else{
91 self.vipView.hidden = 1;
92 self.nameView.textColor = [UIColor blackColor];
93 }
94 }
95
96
97 //计算尺寸
98 -(void)setingFrame{
99 self.iconView.frame = self.modelframe.touF;
100 self.nameView.frame = self.modelframe.nameF;
101 self.textView.frame = self.modelframe.textF;
102 self.vipView.frame = self.modelframe.vipF;
103
104 if (self.modelframe.status.picture) {
105
106 self.pictureView.frame = self.modelF.pictureF;
107
108 }
109
110 self.pictureView.frame = self.modelF.pictureF;
111
112 }
113
114
115 //初始化放到这里来
116 + (instancetype)cellWithTableView:(UITableView *)tableView
117 {
118
119 static NSString *ID = @"HHHHH";
120 WTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
121
122 if (cell==nil) {
123 cell = [[WTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
124 }
125 return cell;
126 }
127
128 @end
补充哈( ^_^ )这里cell的.h文件
1 #import <UIKit/UIKit.h>
2 @class ModelFrame;
3 @interface WTableViewCell : UITableViewCell
4 @property(nonatomic,retain)ModelFrame *modelframe;
5
6 + (instancetype)cellWithTableView:(UITableView *)tableView;
7 @end
数据模型model.h
#import <Foundation/Foundation.h>
@interface Modelstaue : NSObject
@property(nonatomic,copy)NSString *text;
@property(nonatomic,copy)NSString *tou;
@property(nonatomic,copy)NSString *name;
@property (nonatomic, copy) NSString *picture;
@property(nonatomic,assign)NSString *vip;
//将字典转化为模型
-(instancetype)initWithmodel:(NSDictionary *)dic;
初始cell的类方法
+(instancetype)modelWithstaue:(NSDictionary *)dic;
@end
数据模型model.m
#import "Model.h"
@implementation Modelstaue
+(instancetype)modelWithstaue:(NSDictionary *)dic{
return [[self alloc]initWithstaue:dic];
}
-(instancetype)initWithstaue:(NSDictionary *)dic{
if (self = [super init]) {
[self setValuesForKeysWithDictionary:dic];
}
return self;
}
@end
终于来到了vc.m文件里面了,只展示部分代码,其他的都很简单了
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.allmodel.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//初始化和赋值的代码不放在这里,控制器好轻松。。。。仅仅三句代码
WTableViewCell *cell = [WTableViewCell cellWithTableView:tableView];
cell.modelframe = self.allmodel[indexPath.row];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
ModelFrame *mof = _allmodel[indexPath.row];
return mof.cellHeight;
}