通过代码自定义高度不一致的UITableViewCell

1.新建一个继承自UITableViewCell的类

2.重写initWithStyle:reuseIdentifier:方法

Ø添加所有需要显示的子控件(不需要设置子控件的数据和frame,  子控件要添加到contentView中)
Ø进行子控件一次性的属性设置(有些属性只需要设置一次, 比如字体\固定的图片)

3.提供2个模型

Ø数据模型:存放文字数据\图片数据
Øframe模型: 存放数据模型\所有子控件的frame\cell的高度

4.cell拥有一个frame模型(不要直接拥有数据模型)

5.重写frame模型属性的setter方法:在这个方法中设置子控件的显示数据和frame

6.frame模型数据的初始化已经采取懒加载的方式(每一个cell对应的frame模型数据只加载一次)





源代码:

//---- HXXStauts---
#import <Foundation/Foundation.h>

@interface
#import <Foundation/Foundation.h>

@interface HXXStauts :NSObject

/**
 *  昵称
 */
@property(nonatomic,copy)NSString *name;
/**
 *  头像
 */
@property(nonatomic,copy)NSString *icon;
/**
 *  配图
 */
@property(nonatomic,copy)NSString *picture;
/**
 *  内容
 */
@property(nonatomic,copy)NSString *text;
/**
 *  vip
 */
@property(nonatomic,assign)BOOL vip;

+(instancetype)statusWithDict:(NSDictionary *)dict;
-(instancetype)initWithDict:(NSDictionary *)dict;

@end

: NSObject

/**
 *  昵称
 */
@property(nonatomic,copy)NSString *name;
/**
 *  头像
 */
@property(nonatomic,copy)NSString *icon;
/**
 *  配图
 */
@property(nonatomic,copy)NSString *picture;
/**
 *  内容
 */
@property(nonatomic,copy)NSString *text;
/**
 *  vip
 */
@property(nonatomic,assign)BOOL vip;

+(instancetype)statusWithDict:(NSDictionary *)dict;
-(instancetype)initWithDict:(NSDictionary *)dict;

@end
#import "HXXStauts.h"

@implementation HXXStauts

+(instancetype)statusWithDict:(NSDictionary *)dict;
{
   return [[selfalloc]initWithDict:dict];
}
-(instancetype)initWithDict:(NSDictionary *)dict;
{
   if (self = [superinit])
    {
        [selfsetValuesForKeysWithDictionary:dict];
    }
    return self;
}

@end


//----HXXStatusFrame-----
#import <Foundation/Foundation.h>
@class HXXStauts;

@interface HXXStatusFrame :NSObject
/**
 *头像的frame
 */
@property(nonatomic,assign,readonly)CGRect  iconFrame;
/**
 *  昵称的frame
 */
@property(nonatomic,assign,readonly)CGRect  nameFrame;
/**
 *  会员图标的frame
 */
@property(nonatomic,assign,readonly)CGRect  vipFrame;
/**
 *  正文的frame
 */
@property(nonatomic,assign,readonly)CGRect  textFrame;
/**
 *  配图的frame
 */
@property(nonatomic,assign,readonly)CGRect  pictureFrame;
/**
 *  cell的高度
 */
@property(nonatomic,assign,readonly)CGFloat  cellHeight;

/**
 *  status的数据模型
 */
@property(nonatomic,strong) HXXStauts *status;

@end

//昵称字体
#define HXXNameFont [UIFont systemFontOfSize:14]

//正文字体
#define HXXTextFont [UIFont systemFontOfSize:15]
#import "HXXStatusFrame.h"
#import "HXXStauts.h"

@implementation HXXStatusFrame

-(void)setStatus:(HXXStauts *)status
{
   _status =  status;
    
    //子控件之间的间距
   CGFloat padding =10;
    
    //头像的frame
   CGFloat iconX = padding;
   CGFloat iconY = padding;
   CGFloat iconW =30;
   CGFloat iconH =30;
   _iconFrame =CGRectMake(iconX, iconY, iconW, iconH);
    
    
    //昵称的frame
   CGSize nameSize = [selfsizeWithText:self.status.namefont:HXXNameFontmaxSize:CGSizeMake(MAXFLOAT,MAXFLOAT)];
   CGFloat nameX =CGRectGetMaxX(_iconFrame) + padding;
   CGFloat nameY = iconY +(iconH - nameSize.height)*0.5;
    
    //该属性被readonly修饰,那么该属性就没有set方法,则不能通过set()方法或者是self.nameFrame的方式来给该属性附值,而只能通过_nameFrame方式来给它附值
   _nameFrame =CGRectMake(nameX, nameY, nameSize.width, nameSize.height);
    
    //会员图标
   CGFloat vipX =CGRectGetMaxX(_nameFrame) + padding;
   CGFloat vipY = nameY;
   CGFloat vipW =14;
   CGFloat vipH =14;
   _vipFrame =CGRectMake(vipX, vipY, vipW, vipH);
    
   //正文
   CGFloat textX = iconX;
   CGFloat textY =CGRectGetMaxY(_iconFrame) + padding;
   CGSize textSize = [selfsizeWithText:self.status.textfont:HXXTextFontmaxSize:CGSizeMake(300,MAXFLOAT)];
   _textFrame =CGRectMake(textX, textY, textSize.width, textSize.height);
    
   //配图
    if (self.status.picture)//有图
    {
       CGFloat pictureX = textX;
       CGFloat pictureY =CGRectGetMaxY(_textFrame) + padding;
       CGFloat pictureW =100;
       CGFloat pictureH =100;
       _pictureFrame =CGRectMake(pictureX, pictureY, pictureW, pictureH);
        
       _cellHeight =CGRectGetMaxY(_pictureFrame) + padding;
    }else
    {
       _cellHeight =CGRectGetMaxY(_textFrame) + padding;
    }
    
}
/**
 * 计算文件的尺寸
 
 *  @param text    需要计算尺寸的文子
 *  @param font    文字的字体ng
 *  @param maxSize 文字的最大尺寸
 *
 *  @return <#return value description#>
 */

-(CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize
{
    //设置要计算高度文字的字体
    NSDictionary *attrs =@{NSFontAttributeName:font};
    
    return [textboundingRectWithSize:maxSizeoptions:NSStringDrawingUsesLineFragmentOriginattributes:attrscontext:nil].size;
}
@end

//-------HXXStatusCell-------
#import <UIKit/UIKit.h>
@class HXXStatusFrame;

@interface HXXStatusCell :UITableViewCell

@property(nonatomic,strong) HXXStatusFrame  *statusFrame;

+ (instancetype)cellWithTableView:(UITableView *)tableView;
@end
// 昵称的字体
#define HXXNameFont [UIFont systemFontOfSize:14]
// 正文的字体
#define HXXTextFont [UIFont systemFontOfSize:15]

#import "HXXStatusCell.h"
#import "HXXStauts.h"
#import "HXXStatusFrame.h"

@interface HXXStatusCell()
/**
 *  头像
 */
@property (nonatomic,weak)UIImageView *iconView;
/**
 *  昵称
 */
@property(nonatomic,weak)UILabel *nameView;
/**
 *  会员图标
 */
@property(nonatomic,weak)UIImageView *vipView;
/**
 *  正文
 */
@property(nonatomic,weak)UILabel *textView;
/**
 *  配图
 */
@property(nonatomic,weak)UIImageView *pictureView;

@end

@implementation HXXStatusCell

/**
 *构造方法(在初始化对象的时候会调用)
 *一般在这个方法中添加需要显示的子控件
 */
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
   self = [superinitWithStyle:stylereuseIdentifier:reuseIdentifier];
   if (self)
    {
       //头像
       UIImageView *iconView = [[UIImageViewalloc]init];
        [self.contentViewaddSubview:iconView];
        //iconView的是weak类型的,所以不用self.iconView = [[UIImageView alloc]init];直接初始化,因为weak只作用于这一行;
       self.iconView = iconView;
        
        
       //昵称
       UILabel *nameView = [[UILabelalloc]init];
        nameView.font =HXXNameFont;
        [self.contentViewaddSubview:nameView];
       self.nameView = nameView;
        
        
       //会员图标
       UIImageView *vipView = [[UIImageViewalloc]init];
        vipView.image = [UIImageimageNamed:@"vip"];
        [self.contentViewaddSubview:vipView];
       self.vipView = vipView;
        
       //正文
       UILabel *textView = [[UILabelalloc]init];
        textView.numberOfLines =0;
        textView.font =HXXTextFont;
        [self.contentViewaddSubview:textView];
       self.textView = textView;
        
       //配图
       UIImageView *pictureView = [[UIImageViewalloc]init];
        [self.contentViewaddSubview:pictureView];
       self.pictureView = pictureView;
    }
    return self;
}

/**
 *  在这个方法中设置子控件的frame和显示的数据
 *
 
 */
-(void)setStatusFrame:(HXXStatusFrame *)statusFrame
{
   _statusFrame = statusFrame;
    
    //设置数据
    [selfsettingData];
    
    //设置frame
    [selfsettingFrame];
    
}
/**
 * 设置数据
 */
-(void)settingData
{
    //微博数据
    HXXStauts *stauts =self.statusFrame.status;
    
   //头像
   self.iconView.image = [UIImageimageNamed:stauts.icon];
   //昵称
   self.nameView.text = stauts.name;
    
    //会员图标
   if (stauts.vip)
    {
       self.vipView.hidden =NO;
       self.nameView.textColor = [UIColorredColor];
    }
   else
    {
       self.vipView.hidden =YES;
       self.nameView.textColor = [UIColorblackColor];
    }
    
   //正文
   self.textView.text = stauts.text;
    
   //配图
   if (stauts.picture)
    {
       self.pictureView.hidden =NO;
       self.pictureView.image = [UIImageimageNamed:stauts.picture];
    }
   else
    {
       self.pictureView.hidden =YES;
    }
}

/**
 *  计算文字尺寸
 *
 *  @param text    需要计算尺寸的文字
 *  @param font    文字的字体
 *  @param maxSize 文字的最大尺寸
 */
- (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize
{
    NSDictionary *attrs =@{NSFontAttributeName : font};
    return [textboundingRectWithSize:maxSizeoptions:NSStringDrawingUsesLineFragmentOriginattributes:attrscontext:nil].size;
}


/**
 *  设置frame
 */
-(void)settingFrame
{
   //头像
    self.iconView.frame =self.statusFrame.iconFrame;
   //昵称
    self.nameView.frame =self.statusFrame.nameFrame;
    //会员图标
    self.vipView.frame =self.statusFrame.vipFrame;
   //正文
    self.textView.frame =self.statusFrame.textFrame;
   //配图
    if (self.statusFrame.status.picture)
    {
        self.pictureView.frame =self.statusFrame.pictureFrame;
    }
}

+(instancetype)cellWithTableView:(UITableView *)tableView
{
   staticNSString *ID =@"status";
    HXXStatusCell *cell = [tableViewdequeueReusableCellWithIdentifier:ID];
   if (cell ==nil)
    {
        cell = [[HXXStatusCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:ID];
    }
   return cell;
}
@end

//-------HXXViewController----
#import "HXXViewController.h"
#import "HXXStatusCell.h"
#import "HXXStatusFrame.h"
#import "HXXStauts.h"

@interface HXXViewController ()<UITableViewDataSource,UITableViewDelegate>

/**
 *  存放所有的cell的frame模型数据
 */
@property(nonatomic,strong) NSArray  *statusFrames;
@end

@implementation HXXViewController

- (void)viewDidLoad
{
    [superviewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

-(NSArray *)statusFrames
{
    if (_statusFrames ==nil)
    {
        //获取plist的全路径
        NSString *path = [[NSBundlemainBundle]pathForResource:@"weibo.plist"ofType:nil];
       //加载数据
       NSArray *dicArray = [NSArrayarrayWithContentsOfFile:path];
        
        //将dictArray里面的所有字典转成模型对象,放到新的数组中
       NSMutableArray *statusFrameArray = [NSMutableArrayarray];
       for (NSDictionary *dicin dicArray)
        {
           HXXStauts *status = [HXXStautsstatusWithDict:dic];
           HXXStatusFrame *statusFrame = [[HXXStatusFramealloc]init];
            statusFrame.status = status;
            
            [statusFrameArrayaddObject:statusFrame];
            
        }
       _statusFrames = statusFrameArray;
    }
    return_statusFrames;
}

//隐藏状态栏
-(BOOL)prefersStatusBarHidden
{
    return YES;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    returnself.statusFrames.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //创建cell
   HXXStatusCell *cell = [HXXStatusCellcellWithTableView:tableView];
    //在这个方法中算好cell的高度
    cell.statusFrame =self.statusFrames[indexPath.row];
    
    //返回cell
   return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //取出这行对应frame的模型
   HXXStatusFrame  *statusFrame =self.statusFrames[indexPath.row];
    return statusFrame.cellHeight;
}
- (void)didReceiveMemoryWarning
{
    [superdidReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

如果想要完整的zip文件的(包括完整的素材的)朋友可以给我留言或者私信我!





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值