【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
等高的Cell
一、storyboard方式
创建一个继承自UITableViewCell的子类
在storyboard中
- 往cell里面增加需要用到的子控件
- 设置cell的重用标识
- 设置cell的class为我刚才创建的那个Cell类型XXDealCell
3. 在控制器中
- 利用重用标识找到cell
- 给cell传递模型数据
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.deals.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *ID = @"deal";
XXDealCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
//取出模型数据
cell.deal = self.deals[indexPath.row];
return cell;
}
4.在XXDealCell中,将storyboard中的子控件连线到类扩展中,并且提供一个模型属性,重写模型的set方法,在这个方法中设置模型数据到子控件上。
//
// XXDealCell.m
// 自定义等高的cell
//
// Created by Daniel on 16/3/17.
// Copyright © 2016年 Daniel. All rights reserved.
//
#import "XXDealCell.h"
#import "XXDeal.h"
@interface XXDealCell()
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *titleLable;
@property (weak, nonatomic) IBOutlet UILabel *priceLable;
@property (weak, nonatomic) IBOutlet UILabel *buyCountLable;
@end
@implementation XXDealCell
- (void)setDeal:(XXDeal *)deal {
_deal = deal;
//设置数据
self.iconView.image = [UIImage imageNamed:deal.icon];
self.titleLable.text = deal.title;
self.priceLable.text = [NSString stringWithFormat:@"¥%@", deal.price];
self.buyCountLable.text = [NSString stringWithFormat:@"%@人已购买", deal.buyCount];
}
@end
二、xib方式
1.创建一个继承自UITableViewCell的子类,比如XXDealCell
2.创建一个xib文件(文件名建议跟cell的类名一样),比如XXDealCell.xib,拖拽一个UITableViewCell出来,修改cell的class为XXDealCell,设置cell的重用标识,往cell中添加需要用到的子控件
这两步和storyboard方式都是大同小异。
3.在控制器中,利用registerNib...方法注册xib文件,利用重用标识找到cell(如果没有注册xib文件,就需要手动去加载xib文件),给cell传递模型数据。
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([XXDealCell class]) bundle:nil] forCellReuseIdentifier:@"deal"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *ID = @"deal";
XXDealCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
//如果不注册,就要这样手动加载xib
// if(cell == nil) {
// cell = [[[NSBundle mainBundle]loadNibNamed:NSStringFromClass([XXDealCell class]) owner:nil options:nil]lastObject];
// }
//取出模型数据
cell.deal = self.deals[indexPath.row];
return cell;
}
4.在XXDealCell中,将xib中的子控件连线到类扩展中,需要提供一个模型属性,重写模型的set方法,在这个方法中设置模型数据到子控件上,也可以将创建获得cell的代码封装起来(比如cellWithTableView:方法)
//
// XXDealCell.m
// 自定义等高的cell
//
// Created by Daniel on 16/3/17.
// Copyright © 2016年 Daniel. All rights reserved.
//
#import "XXDealCell.h"
#import "XXDeal.h"
@interface XXDealCell()
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *titleLable;
@property (weak, nonatomic) IBOutlet UILabel *priceLable;
@property (weak, nonatomic) IBOutlet UILabel *buyCountLable;
@end
@implementation XXDealCell
- (void)setDeal:(XXDeal *)deal {
_deal = deal;
//设置数据
self.iconView.image = [UIImage imageNamed:deal.icon];
self.titleLable.text = deal.title;
self.priceLable.text = [NSString stringWithFormat:@"¥%@", deal.price];
self.buyCountLable.text = [NSString stringWithFormat:@"%@人已购买", deal.buyCount];
}
+ (instancetype)cellWithTableView:(UITableView *) tableView {
static NSString *ID = @"deal";
XXDealCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if(cell == nil) {
cell = [[[NSBundle mainBundle]loadNibNamed:NSStringFromClass([XXDealCell class]) owner:nil options:nil]lastObject];
}
return cell;
}
@end
- (void)viewDidLoad {
[super viewDidLoad];
// [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([XXDealCell class]) bundle:nil] forCellReuseIdentifier:@"deal"];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.deals.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
XXDealCell *cell = [XXDealCell cellWithTableView:tableView];
//取出模型数据
cell.deal = self.deals[indexPath.row];
return cell;
}
三、代码方式
-------------使用frame
1.创建一个继承自UITableViewCell的子类,比如XXDealCell
- 在initWithStyle:reuseIdentifier:方法中添加子控件,设置子控件的初始化属性(比如文字颜色、字体)等
- 在layoutSubviews方法中设置子控件的frame
- 需要提供一个模型属性,重写模型的setter方法,在这个方法中设置模型数据到子控件
//1、在initWithStyle:reuseIdentifier:方法中添加子控件
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if(self == [super initWithStyle:style reuseIdentifier:reuseIdentifier ]) {
UIImageView *iconView = [[UIImageView alloc]init];
[self.contentView addSubview:iconView];
self.iconView = iconView;
UILabel *titleLable = [[UILabel alloc]init];
[self.contentView addSubview:titleLable];
self.titleLable = titleLable;
UILabel *priceLable = [[UILabel alloc]init];
[self.contentView addSubview:priceLable];
priceLable.textColor = [UIColor orangeColor];
self.priceLable = priceLable;
UILabel *buyCountLable = [[UILabel alloc]init];
[self.contentView addSubview:buyCountLable];
buyCountLable.textAlignment = NSTextAlignmentRight;
buyCountLable.font = [UIFont systemFontOfSize:11];
buyCountLable.textColor = [UIColor lightGrayColor];
self.buyCountLable = buyCountLable;
}
return self;
}
//2、在layoutSubviews方法中设置子控件的frame
- (void)layoutSubviews {
[super layoutSubviews];
//iconView
CGFloat iconX = 10;
CGFloat iconY = 10;
CGFloat iconW = 100;
CGFloat iconH = self.contentView.frame.size.height - 2 * iconY;
self.iconView.frame = CGRectMake(iconX, iconY, iconW, iconH);
//titleLable
CGFloat titleX = CGRectGetMaxX(self.iconView.frame) + 10;
CGFloat titleY = iconY;
CGFloat titleW = self.contentView.frame.size.width - titleX - 10;
CGFloat titleH = 20;
self.titleLable.frame = CGRectMake(titleX, titleY, titleW, titleH);
//priceView
CGFloat priceX = titleX;
CGFloat priceH = 20;
CGFloat priceY = self.contentView.frame.size.height - priceH - 10;
CGFloat priceW = 70;
self.priceLable.frame = CGRectMake(priceX, priceY, priceW, priceH);
//buyCountView
CGFloat buyH = priceH;
CGFloat buyY = self.contentView.frame.size.height - 10 - buyH;
CGFloat buyX = priceX + priceW + 10;
CGFloat buyW = self.contentView.frame.size.width - buyX - 10;
self.buyCountLable.frame = CGRectMake(buyX, buyY, buyW, buyH);
}
//3、重写模型的setter方法
- (void)setDeal:(XXDeal *)deal {
_deal = deal;
//设置数据
self.iconView.image = [UIImage imageNamed:deal.icon];
self.titleLable.text = deal.title;
self.priceLable.text = [NSString stringWithFormat:@"¥%@", deal.price];
self.buyCountLable.text = [NSString stringWithFormat:@"%@人已购买", deal.buyCount];
}
2.在控制器中,利用registerClass...方法注册XMGDealCell类,利用重用标识找到cell(如果没有注册类,就需要手动创建cell,给cell传递模型数据,也可以将创建获得cell的代码封装起来(比如cellWithTableView:方法)。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
XXDealCell *cell = [XXDealCell cellWithTableView:tableView];
//取出模型数据
cell.deal = self.deals[indexPath.row];
return cell;
}
---------------------使用autoLayout
与使用frame不同的是:在initWithStyle:reuseIdentifier:方法中添加子控件后直接添加约束,然后不需要layoutSubviews方法了。其他都是一样的,添加约束使用Masonry。
//1、在initWithStyle:reuseIdentifier:方法中添加子控件
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if(self == [super initWithStyle:style reuseIdentifier:reuseIdentifier ]) {
CGFloat margin = 10;
UIImageView *iconView = [[UIImageView alloc]init];
[self.contentView addSubview:iconView];
self.iconView = iconView;
[iconView makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(100);
make.left.top.equalTo(self.contentView).offset(margin);
make.bottom.equalTo(self.contentView).offset(-margin);
}];
UILabel *titleLable = [[UILabel alloc]init];
[self.contentView addSubview:titleLable];
self.titleLable = titleLable;
[titleLable makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(iconView.right).offset(margin);
make.top.equalTo(iconView);
make.right.equalTo(self.contentView).offset(-margin);
}];
UILabel *priceLable = [[UILabel alloc]init];
[self.contentView addSubview:priceLable];
priceLable.textColor = [UIColor orangeColor];
self.priceLable = priceLable;
[priceLable makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(titleLable);
make.bottom.equalTo(iconView);
}];
UILabel *buyCountLable = [[UILabel alloc]init];
[self.contentView addSubview:buyCountLable];
buyCountLable.textAlignment = NSTextAlignmentRight;
buyCountLable.font = [UIFont systemFontOfSize:11];
buyCountLable.textColor = [UIColor lightGrayColor];
self.buyCountLable = buyCountLable;
[buyCountLable makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(priceLable);
make.right.equalTo(self.contentView).offset(-margin);
make.left.equalTo(priceLable).offset(margin);
}];
}
return self;
}
非等高cell
xib自定义非等高cell
- 在模型中增加一个cellHeight属性,用来存放对应cell的高度
/**
* cell的高度
*/
@property(assign, nonatomic)CGFloat cellHeight;
- 在cell的模型属性setter方法中调用[self layoutIfNeed]方法强制布局,然后计算出模型的cellheight属性值
//强制布局
[self layoutIfNeeded];
- 在控制器中实现tableView:estimatedHeightForRowAtIndexPath:方法,返回一个估计高度
/**
* 返回每一个cell的估计高度
*
* @param tableView
* @param indexPath
*
* @return 只要返回了估计高度,tableView就会先调用tableView:cellForRowAtIndexPath:方法创建cell
* 再调用tableView:heightForRowAtIndexPath:方法获取cell的真实高度
*/
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 100;
}
- 在控制器中实现tableView:heightForRowAtIndexPath:方法,返回cell的真实高度(模型中的cellHeight属性)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
XXStatusCell *cell = [XXStatusCell cellWithTableView:tableView];
//设置数据
cell.status = self.statuses[indexPath.row];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
XXStatus *status = self.statuses[indexPath.row];
return status.cellHeight;
}
2、storyboard方式自定义非等高cell
用storyboard和xib其实大同小异,直接在storyboard中添加子控件并添加约束,设置重用标识,修改cell的类,修改cell为动态创建类型。注意,如果Lable要显示多行的话,Lines要改为0,而且cell高度极端准确,要加一个方法:
- (void)awakeFromNib {
self.contentLable.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;
}
然后获取cell时直接在缓存池中根据重用标识去查找,其他的和xib方式一样。
+ (instancetype)cellWithTableView :(UITableView *)tableView {
return [tableView dequeueReusableCellWithIdentifier:@"status"];
}
来源:oschina
链接:https://my.oschina.net/u/1011331/blog/638908