IOS开发之动态高度的Cell开发详解

应用场景

想必各位coder们在开发中用的最多的就是tableView了,这个控件是非常强大以及实用的,这篇文章即讲解如何根据获取的数据,动态创建Cell。

实现:

首先这种比较“异类”的cell想必还是我们自己创建的好,所以我们将要自定义一个Cell:

,h文件如下:

 #import <UIKit/UIKit.h>  
 #import "DataModel.h"  
 #import "FrameModel.h"  
 @interface SecondCell : UITableViewCell  

 @property(nonatomic,strong)FrameModel *model;  

 +(instancetype)cellWithtableView:(UITableView *)tableview;  

 @end

.m 文件:

//  
//  SecondCell.m  
//  ThirdDemo  
//  
//  Created by JourneyYoung on 16/7/13.  
//  Copyright © 2016年 JourneyYoung. All rights reserved.  
//  

#import "SecondCell.h"  

@interface SecondCell()  

@property(nonatomic,strong)UIImageView *icon;  

@property(nonatomic,strong)UILabel *name;  

@property(nonatomic,strong)UILabel *Maintext;  

//@property(nonatomic,strong)UIImageView *pic;  

@end  

@implementation SecondCell  



+(instancetype)cellWithtableView:(UITableView *)tableview  
{  
static NSString *ID = @"seccell";  
SecondCell *cell = [tableview dequeueReusableCellWithIdentifier:ID ];  
if(!cell)  
{  
cell = [[SecondCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];  
cell.selectionStyle = UITableViewCellSelectionStyleNone;  
}  
else//当页面拉动的时候 当cell存在并且最后一个存在 把它进行删除就出来一个独特的cell我们在进行数据配置即可避免界面重叠  
{  
while ([cell.contentView.subviews lastObject] != nil) {  
[(UIView *)[cell.contentView.subviews lastObject] removeFromSuperview];  
}  
cell = [[SecondCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];  
cell.selectionStyle = UITableViewCellSelectionStyleNone;  
}  

return cell;  
}  


-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier  
{  
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];  
if(self)  
{  
self.icon = [[UIImageView alloc]init];  
[self.contentView addSubview:self.icon];  

self.name = [[UILabel alloc]init];  
self.name.textColor = [UIColor orangeColor];  
self.name.font = [UIFont systemFontOfSize:12.0];  
[self.contentView addSubview:self.name];  

self.Maintext = [[UILabel alloc]init];  
self.Maintext.font = [UIFont systemFontOfSize:12.0];  
self.Maintext.numberOfLines = 0;  
[self.contentView addSubview:self.Maintext];  

//        self.pic = [[UIImageView alloc]init];  
//        [self.contentView addSubview:self.pic];  
}  
return self;  
}  


-(void)setModel:(FrameModel *)model  
{  
_model = model;  
[self setframe];  
[self setdate];  

}  



-(void)setdate  
{  
DataModel *model = self.model.datamodel;  

self.icon.image = [UIImage imageNamed:model.icon];  

self.name.text = model.nickname;  

self.Maintext.text = model.text;  

//    if(model.picArray.count>0)  
//    {  
//        //self.pic.image = [UIImage imageNamed:model.pic];  
//        for(int i= 0;i<model.picArray.count;i++)  
//        {  
//              
//        }  
//    }  
//      

}  

-(void)setframe  
{  
self.icon.frame = self.model.IconF;  

self.name.frame = self.model.NickF;  

self.Maintext.frame = self.model.TextF;  

if(self.model.datamodel.picArray.count>0)  
{  
//        self.pic.frame = self.model.PicF;  
//        self.pic.hidden = NO;  
for(int i=0;i<self.model.PicFArray.count;i++)  
{  
NSValue *value = self.model.PicFArray[i];  
CGRect rec = [value CGRectValue];  
UIImageView *imageView = [[UIImageView alloc]initWithFrame:rec];  
imageView.image = [UIImage imageNamed:self.model.datamodel.picArray[i]];  
[self.contentView addSubview:imageView];  
}  
}  
else  
{  
//self.pic.hidden = YES;  
}  
}  

- (void)awakeFromNib {  
[super awakeFromNib];  
// Initialization code  
}  

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {  
[super setSelected:selected animated:animated];  

// Configure the view for the selected state  
}  

@end

从上述代码中可以看出,我们进行了两次赋值,第一次是对cell中的控件的显示数值进行赋值,第二次是对cell中的控价坐标进行赋值,这两次赋值是通过模型来办到的。先来看看数据模型DataModel:

#import <Foundation/Foundation.h>  

@interface DataModel : NSObject  

@property(nonatomic,copy) NSString *text;  

@property(nonatomic,copy) NSString *icon;  

@property(nonatomic,copy) NSString *nickname;  

@property(nonatomic,copy) NSArray *picArray;  

- (id)initWithDict:(NSDictionary *)dict;  
+ (id)ModelWithDict:(NSDictionary *)dict;  

@end

坐标模型:

#import "DataModel.h"  

@implementation DataModel  

- (id)initWithDict:(NSDictionary *)dict  
{  
if (self = [super init]) {  
[self setValuesForKeysWithDictionary:dict];  
}  
return self;  
}  

+ (id)ModelWithDict:(NSDictionary *)dict  
{  
return [[self alloc] initWithDict:dict];  
}

坐标模型:

#import <Foundation/Foundation.h>  
#import "UIKit/UIKit.h"  
@class DataModel;  


@interface FrameModel : NSObject  


@property(nonatomic,assign)CGRect IconF;  

@property(nonatomic,assign)CGRect NickF;  

@property(nonatomic,assign)CGRect TextF;  

@property(nonatomic,strong)NSMutableArray *PicFArray;  

@property(nonatomic,assign)CGFloat cellHeigth;  

@property(nonatomic,strong)DataModel *datamodel;

每个参数都对应着每个控件的坐标,其中PicArray数组存放的是每个UIImageview的坐标,因为服务器传给你的想必是个图片地址数组而不是仅仅只有一个图片。

在.m文件中根据取到的数据模型来计算控件坐标:

#import "FrameModel.h"  
#import "DataModel.h"  
@implementation FrameModel  

-(void)setDatamodel:(DataModel *)datamodel  
{  
_datamodel = datamodel;  

// CGFloat padding = 10;  

//头像frame  
self.IconF = CGRectMake(10, 10, 30, 30);  

CGFloat nickLabelX = CGRectGetMaxX(self.IconF)+20;  
//昵称的frame  
CGSize nameSize = [self sizeWithString:self.datamodel.nickname font:[UIFont systemFontOfSize:12.0] maxSize:CGSizeMake(200, 200)];  
self.NickF = CGRectMake(nickLabelX, 10+(30-nameSize.height)*0.5, nameSize.width, nameSize.height);  


//正文frame  
CGSize textsize = [self sizeWithString:self.datamodel.text font:[UIFont systemFontOfSize:12.0] maxSize:CGSizeMake([UIScreen mainScreen].bounds.size.width-20, 200)];  

self.TextF = CGRectMake(10, CGRectGetMaxY(self.IconF)+10, textsize.width, textsize.height);  

//有配图的话图的frame及cell高度  
if(self.datamodel.picArray.count>0)  
{  
//一张图  
if(self.datamodel.picArray.count == 1)  
{  
CGRect PicF = CGRectMake(10, CGRectGetMaxY(self.TextF)+20, [UIScreen mainScreen].bounds.size.width-20, 150);  
NSValue *value = [NSValue valueWithCGRect:PicF];  
[self.PicFArray addObject:value];  
self.cellHeigth = CGRectGetMaxY(PicF) +10;  
}  
//两张图  
else if(self.datamodel.picArray.count == 2)  
{  
CGRect PicF_01 = CGRectMake(10, CGRectGetMaxY(self.TextF)+20, ([UIScreen mainScreen].bounds.size.width-30)*0.5, ([UIScreen mainScreen].bounds.size.width-30)*0.5);  
NSValue *value_01 = [NSValue valueWithCGRect:PicF_01];  
[self.PicFArray addObject:value_01];  

CGRect PicF_02 = CGRectMake(20+PicF_01.size.width, CGRectGetMaxY(self.TextF)+20, ([UIScreen mainScreen].bounds.size.width-30)*0.5, ([UIScreen mainScreen].bounds.size.width-30)*0.5);  
NSValue *value_02 = [NSValue valueWithCGRect:PicF_02];  
[self.PicFArray addObject:value_02];  
self.cellHeigth = CGRectGetMaxY(PicF_01) +10;  
}  
//大于两张  
else  
{  
CGFloat wi = ([UIScreen mainScreen].bounds.size.width-40)/3;  
for(int i=0;i<self.datamodel.picArray.count;i++)  
{  
CGRect rec = CGRectMake(10+(i%3)*(wi+10), CGRectGetMaxY(self.TextF)+20+(i/3)*(wi+10), wi, wi);  
NSValue *value = [NSValue valueWithCGRect:rec];  
[self.PicFArray addObject:value];  
self.cellHeigth = rec.origin.y+rec.size.height+10;  
}  
}  
}  
else  
{  
self.cellHeigth = CGRectGetMaxY(self.TextF) +10;  
}  
}  




//计算文本的宽高  

- (CGSize)sizeWithString:(NSString *)str font:(UIFont *)font maxSize:(CGSize)maxSize  
{  
NSDictionary *dict = @{NSFontAttributeName : font};  
CGSize size =  [str boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil].size;  
return size;  
}  

//懒加载  

-(NSMutableArray *)PicFArray  
{  
if(!_PicFArray)  
{  
self.PicFArray = [NSMutableArray array];  
}  
return _PicFArray;  
}  


@end

由此一来我们获取到两个模型,我们在自定义的cell中就可以进行赋值,在主控制器中,我们这样进行处理:

创建cell的代码,自不必说:

SecondCell *cell = [SecondCell cellWithtableView:tableView];  
cell.model = self.FrameArray[indexPath.row];  
return cell;

上面代码中FrameArray数组就是存放坐标模型的数组,将其对应赋值给cell,就能得到我们所想要的。

工程文件我已上传,在这里:传送门

本文总阅读量