首页 > 技术文章 > IOS开发-cell的动态高度

chenhongios 2015-09-09 22:42 原文

 

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;
    
}

 

 

 

 

推荐阅读