UI基础之UITableView案例微博----自定义cell利用代码

第一步:创建微博模型,完成字典转模型

#import <Foundation/Foundation.h>
//#import <UIKit/UIKit.h>
/**
 *  第一步:创建微博模型,完成字典转模型
 */
@interface LLWeiBo : NSObject

/**
 *  icon
 */
@property (nonatomic, copy) NSString *icon;

/**
 *  name
 */
@property (nonatomic, copy) NSString *name;

/**
 *  vip
 */
@property (nonatomic, assign, getter=isVip) BOOL vip;

/**
 *  text
 */
@property (nonatomic, copy) NSString *text;

/**
 *  picture
 */
@property (nonatomic, copy) NSString *picture;


- (instancetype)initWithDic:(NSDictionary *)dic;
+ (instancetype)weiBoWithDic:(NSDictionary *)dic;

@end
#import "LLWeiBo.h"

@implementation LLWeiBo

- (instancetype)initWithDic:(NSDictionary *)dic
{
    if (self = [super init]) {
        
        [self setValuesForKeysWithDictionary:dic];
    }
    return self;
}

+ (instancetype)weiBoWithDic:(NSDictionary *)dic
{
    return [[self alloc] initWithDic:dic];
}


@end

第二步:确定cell的高度

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#define NAMEFONT [UIFont systemFontOfSize:14]
#define TEXTFONT [UIFont systemFontOfSize:15]
@class LLWeiBo;
@interface LLWeiBoFrame : NSObject

@property (nonatomic, strong) LLWeiBo *weiBo;

@property (nonatomic, assign, readonly) CGRect iconF;

@property (nonatomic, assign, readonly) CGRect nameF;

@property (nonatomic, assign, readonly) CGRect vipF;

@property (nonatomic, assign, readonly) CGRect textF;

@property (nonatomic, assign, readonly) CGRect picF;

@property (nonatomic, assign, readonly) CGFloat cellHeight;

@end
#import "LLWeiBoFrame.h"
#import "LLWeiBo.h"
@implementation LLWeiBoFrame

- (void)setWeiBo:(LLWeiBo *)weiBo
{
    _weiBo = weiBo;
    CGFloat margin = 10.0;
    
    // 头像
    CGFloat iconX = margin;
    CGFloat iconY = margin;
    CGFloat iconHW = 30;
    _iconF = CGRectMake(iconX, iconY, iconHW, iconHW);
    
    /**
     *  设置到计算文字的size 与三个变量有关1,文字,2,字体,3,文字要显示最大size的限制
     */
    // 名称
    CGFloat nameX = CGRectGetMaxX(_iconF) + margin;
    CGSize nameSize = [self sizeOfText:self.weiBo.name Font:NAMEFONT MaxSize:CGSizeMake(MAXFLOAT, MAXFLOAT)];
    CGFloat nameY = (iconHW - nameSize.height) * 0.5 + iconY;
    _nameF = CGRectMake(nameX, nameY, nameSize.width, nameSize.height);
    
    // 会员
    CGFloat vipX = CGRectGetMaxX(_nameF) + margin;
    CGFloat vipY = nameY;
    CGFloat vipWH = 15;
    _vipF = CGRectMake(vipX, vipY, vipWH, vipWH);
    
    // 正文
    CGFloat textX = margin;
    CGFloat textY = CGRectGetMaxY(_iconF) + margin;
    CGSize  textSize = [self sizeOfText:self.weiBo.text Font:TEXTFONT MaxSize:CGSizeMake(300, MAXFLOAT)];
    _textF = CGRectMake(textX, textY, textSize.width, textSize.height);
    
    // 图片
    CGFloat picX = margin;
    CGFloat picY = CGRectGetMaxY(_textF) + margin;
    CGFloat picWH = 100;
    _picF = CGRectMake(picX, picY, picWH, picWH);
    
    if (self.weiBo.picture) {
        
        _cellHeight = CGRectGetMaxY(_picF) + margin;
    } else {
        _cellHeight = CGRectGetMaxY(_textF) + margin;
    }
}

#pragma mark - 计算文字size
- (CGSize)sizeOfText:(NSString *)text Font:(UIFont *)font MaxSize:(CGSize)maxSize
{
    NSDictionary *attrs = @{NSFontAttributeName : font };
    return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size;
}

@end

第3步:创建cell展示数据

#import <UIKit/UIKit.h>
@class LLWeiBoFrame;

@interface LLWeiBoCell : UITableViewCell

@property (nonatomic, strong) LLWeiBoFrame *weiBoFrame;

+ (instancetype)weiBoCell:(UITableView *)tableView;

@end
#import "LLWeiBoCell.h"
#import "LLWeiBoFrame.h"
#import "LLWeiBo.h"
@interface LLWeiBoCell ()

@property (nonatomic, weak) UIImageView *iconView;
@property (nonatomic, weak) UILabel *nameView;
@property (nonatomic, weak) UIImageView *vipView;
@property (nonatomic, weak) UILabel *textView;
@property (nonatomic, weak) UIImageView *picView;

@end

@implementation LLWeiBoCell


+ (instancetype)weiBoCell:(UITableView *)tableView
{
    static NSString *ID = @"weiBoCell";
    LLWeiBoCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (!cell) {
        
        /**
         cell如果不存在,我们自定义创建cell,或者通过storyboard创建,或者加载xib,这个我们自定义创建cell
         */
        cell = [[LLWeiBoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }
    return cell;
}

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        
        /**
         *  初始化cell创建cell的子控件
         */
        
        // 头像
        UIImageView *iconView = [[UIImageView alloc] init];
        [self.contentView addSubview:iconView];
        self.iconView = iconView;
        
        // 名称
        UILabel *nameView = [[UILabel alloc] init];
        [self.contentView addSubview:nameView];
        nameView.textColor = [UIColor blackColor];
        nameView.font = NAMEFONT;
        self.nameView = nameView;
        
        // 会员
        UIImageView *vipView = [[UIImageView alloc] init];
        [self.contentView addSubview:vipView];
        vipView.image = [UIImage imageNamed:@"vip"];
        self.vipView = vipView;

        // 正文
        UILabel *textView = [[UILabel alloc] init];
        [self.contentView addSubview:textView];
        textView.numberOfLines = 0;
        textView.font = TEXTFONT;
        self.textView = textView;

        // 图片
        UIImageView *picView = [[UIImageView alloc] init];
        [self.contentView addSubview:picView];
        self.picView = picView;
        
    }
    return self;
}



- (void)setWeiBoFrame:(LLWeiBoFrame *)weiBoFrame
{
    _weiBoFrame = weiBoFrame;
    // 1,设置cell子控件数据
    [self setSubviewsDate];
    // 2,设置cell子控件的frame
    [self setSubviewFrame];

}

- (void)setSubviewsDate
{
    LLWeiBo *weiBo = self.weiBoFrame.weiBo;
    self.iconView.image = [UIImage imageNamed:weiBo.icon];
    self.nameView.text = weiBo.name;
    
    /**
     *  因为cell的重用问题,这里赋值数据要全部重新赋值,否则容易出错
     */
    if (weiBo.isVip) {
        self.vipView.hidden = NO;
        self.nameView.textColor = [UIColor redColor];
    } else {
        self.vipView.hidden = YES;
        self.nameView.textColor = [UIColor blackColor];
    }
    
    self.textView.text = weiBo.text;
    
    if (weiBo.picture) {
        
        self.picView.image = [UIImage imageNamed:weiBo.picture];
        self.picView.hidden = NO;
    } else{
        
        self.picView.hidden = YES;
    }
}

- (void)setSubviewFrame
{
    
    self.iconView.frame = self.weiBoFrame.iconF;
    self.nameView.frame = self.weiBoFrame.nameF;
    self.vipView.frame = self.weiBoFrame.vipF;
    self.textView.frame = self.weiBoFrame.textF;
    self.picView.frame = self.weiBoFrame.picF;
}


@end

第4步展示cell

#import "LLViewController.h"
#import "LLWeiBo.h"
#import "LLWeiBoCell.h"
#import "LLWeiBoFrame.h"
@interface LLViewController ()

@property (nonatomic, strong) NSArray *weiBoFrames;

@end

@implementation LLViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    self.tableView.rowHeight = 200;
}

#pragma mark - 懒加载数据模型
- (NSArray *)weiBoFrames
{
    if (!_weiBoFrames) {
        
        NSString *path = [[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil];
        NSArray *dicArray = [NSArray arrayWithContentsOfFile:path];
        NSMutableArray *tmpArray = [[NSMutableArray alloc] initWithCapacity:dicArray.count];
        
        for (NSDictionary *dic in dicArray) {
            LLWeiBoFrame *weiBoFrame = [[LLWeiBoFrame alloc] init];
            LLWeiBo *weibo = [LLWeiBo weiBoWithDic:dic];
            weiBoFrame.weiBo = weibo;
            [tmpArray addObject:weiBoFrame];
        }
        _weiBoFrames = tmpArray;
        
    }
    return _weiBoFrames;
}

#pragma mark - tableView的数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return self.weiBoFrames.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    // 1,创建cell
    LLWeiBoCell *cell = [LLWeiBoCell weiBoCell:tableView];
    
    // 2,给cell设置数据
    cell.weiBoFrame = self.weiBoFrames[indexPath.row];
    
    return cell;

}


#pragma mark - 代理的方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [self.weiBoFrames[indexPath.row] cellHeight];
}


@end

补充: 

使用纯代码自定义一个tableview的步骤

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

2.重写initWithStyle:reuseIdentifier:方法

添加所有需要显示的子控件(不需要设置子控件的数据和frame,  子控件要添加到contentView中)

进行子控件一次性的属性设置(有些属性只需要设置一次, 比如字体固定的图片)

3.提供2个模型

数据模型: 存放文字数据图片数据

frame模型: 存放数据模型所有子控件的framecell的高度

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

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

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

 代码:

/**
* 计算文本的宽高
*
* @param str 需要计算的文本
* @param font 文本显示的字体
* @param maxSize 文本显示的范围
*
* @return 文本占用的真实宽高
*/
- (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;
}

原文地址:https://www.cnblogs.com/-boy/p/4129039.html