您的位置:首页 > 产品设计 > UI/UE

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

2014-11-28 17:21 441 查看
第一步:创建微博模型,完成字典转模型

#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模型: 存放数据模型\所有子控件的frame\cell的高度

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: