内容概要:
表视图之自定义单元格
一、直接在cell.contentView上添加组件来自定义cell
//
返回
cell
- ( UITableViewCell *)tableView:( UITableView *)tableView cellForRowAtIndexPath:( NSIndexPath *)indexPath{
NSString * id = @"Cell" ;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier : id ];
- ( UITableViewCell *)tableView:( UITableView *)tableView cellForRowAtIndexPath:( NSIndexPath *)indexPath{
NSString * id = @"Cell" ;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier : id ];
if (cell ==nil) {
//调用自定义方法:在此方法中我们在cell上添加了各种组件
cell = [
self
myCellView
];
}
//调用自定义方法:为组件中的属性赋值
[
self
setCell
:indexPath
UITableViewCell
:cell];
return cell;
}
//
自定义方法:返回添加了各种组件的
cell
- (
UITableViewCell
*)myCellView{
//设置id
NSString
*
id
=
@"Cell"
;
UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:id];
//
显示图片的组件
UIImageView
*imgView = [[
UIImageView
alloc
]
initWithFrame
:
CGRectMake
(20, 10, 37*2, 60*2)];
imgView. tag = 100;
imgView. tag = 100;
[cell.contentView addSubview:imgView];
}
//自定义方法:
为
cell
设置参数
- (
void
)setCell:(
NSIndexPath
*)indexPath UITableViewCell:(
UITableViewCell
*)cell{
//取出当前字典(即数据源)
NSDictionary
*dic =
_dataArr
[indexPath.
row
];
// 设置属性值
UIImageView *imgView1 = ( UIImageView *)[cell. contentView viewWithTag :100];
// 设置属性值
UIImageView *imgView1 = ( UIImageView *)[cell. contentView viewWithTag :100];
imgView1.image = [UIImage imageNamed:[dic objectForKey:@"image"] ];
}
二、xib文件自定义单元格
1.创建空的MyCell.xib文件,拖进TableViewCell组件,
为其设置id(“Cell")
2在cell组件中添加各种需要的组件,并为其设置tag值,便于在代码中取出为其设置实际的值
3.由于cell的高度不能在xib文件中设置,需要在代码中指定高度
4.在返回单元格的方法中通过如下方法获取并复用单元格
NSString
*
id
=
@"Cell"
;
//通过id来获取可复用的单元格
UITableViewCell
*cell = [tableView
dequeueReusableCellWithIdentifier
:
id
];
//如果没有获取到可用的单元格,就从xib中获取一个自定义的单元格
if
(cell ==
nil
) {
//使用xib方法
cell = [[[NSBundle mainBundle] loadNibNamed:@"MyCell" owner:niloptions:nil] lastObject];
}
//获取单元格后,通过tag值获取cell中的组件,并设置单元格中的值
...
//最后返回单元格
return
cell;
}
三、storyBoard结合面向对象的思想复用单元格
第一步:storyBoard中的处理
1.通过storyBoard在视图控制器上添加一个Table View组件,并且连接代理到视图控制器,再添加一个复用单元格,
2.在单元格上添加各种自己需要的组件(不需要设置tag值)但是
要设置id属性(以便在视图控制器中取出复用单元格)
第二步:自定义cell类中的处理
1.创建自定义的MyCell类,使其继承于3TableViewCell子类
2.将在story的cell上面组件后拖进MyCell的.h文件中,作为自定义cell的成员变量,在MyCell类中还要添加数据源属性如下:
@property
(
weak
,
nonatomic
)
IBOutlet
UIImageView
*imgView;
@property ( weak , nonatomic ) IBOutlet UILabel *titleLabel;
@property ( weak , nonatomic ) IBOutlet UILabel *yearLabel;
@property ( weak , nonatomic ) IBOutlet UILabel *ratingLabel;
// 数据源
@property ( nonatomic , strong ) NSDictionary *dataDic;
@property ( weak , nonatomic ) IBOutlet UILabel *titleLabel;
@property ( weak , nonatomic ) IBOutlet UILabel *yearLabel;
@property ( weak , nonatomic ) IBOutlet UILabel *ratingLabel;
// 数据源
@property ( nonatomic , strong ) NSDictionary *dataDic;
3.使用继承后的子类有下面的方法
- (void)awakeFromNib {
//当视图从xib或者storyboard中加载时,走这个方法,相当于初始化方法
}
4.在tableView返回单元格的房中,我们调用了单元格设置数据源的方法,也就是如下的方法,这样cell中各组件的属性值就都有了
//通过set方法,设置了数据源也设置了其他属性
- (
void
)setDataDic:(
NSDictionary
*)dataDic
{
if ( _dataDic != dataDic) {
_dataDic = dataDic;
}
// 此时能够确保值已经传过来了
{
if ( _dataDic != dataDic) {
_dataDic = dataDic;
}
// 此时能够确保值已经传过来了
self.imgView.image = [UIImage imageNamed:[self.dataDicobjectForKey:@"image"]];
self
.
titleLabel
.
text
= [
self
.
dataDic
objectForKey
:
@"title"
];
self
.
yearLabel
.
text
= [
self
.
dataDic
objectForKey
:
@"year"
];
self
.
ratingLabel
.
text
= [
self
.
dataDic
objectForKey
:
@"rating"
];
}
第三步:视图控制器中对返回单元格的操作
//1.
设置数据源
//2.
返回行数(和组数)
//3. 返回单元格的高度(在 storyboard 中设置单元格高度无效)
// 这里设置高度有两种方法
// (1) 在 story 中为 tableView 设置 tag 值,然后在此控制器中取出设置行高
// (2)通过代理方法返回行高
//4. 返回单元格
- ( UITableViewCell *)tableView:( UITableView *)tableView cellForRowAtIndexPath:( NSIndexPath *)indexPath
{
//V(View) :单元格
//通过面向对象的方法,把stroryBoard中的cell封装成了TableViewCell的子类,所以在这里就使用了子类MovieCell
//3. 返回单元格的高度(在 storyboard 中设置单元格高度无效)
// 这里设置高度有两种方法
// (1) 在 story 中为 tableView 设置 tag 值,然后在此控制器中取出设置行高
// (2)通过代理方法返回行高
//4. 返回单元格
- ( UITableViewCell *)tableView:( UITableView *)tableView cellForRowAtIndexPath:( NSIndexPath *)indexPath
{
//V(View) :单元格
//通过面向对象的方法,把stroryBoard中的cell封装成了TableViewCell的子类,所以在这里就使用了子类MovieCell
MovieCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"forIndexPath:indexPath];
//在控制器中,我们不应该太多去设置视图自己需要显示的内容,控制器充当MVC架构模式中的C,需要做的应该是把M---》V
//M(Model):数据源
NSDictionary *contentDic = self.data[indexPath.row ];
//contentDic----> Cell
//dataDic 是自定义单元格对象的属性,在设置单元格的这个属性的时候,通过 set 方法也会初始化 cell 中的各种属性值
cell. dataDic = contentDic;
return cell;
NSDictionary *contentDic = self.data[indexPath.row ];
//contentDic----> Cell
//dataDic 是自定义单元格对象的属性,在设置单元格的这个属性的时候,通过 set 方法也会初始化 cell 中的各种属性值
cell. dataDic = contentDic;
return cell;
}
四、MVC架构模式来使用单元格
MVC的架构思想:
Model数据层:从资源文件中获取数据,并取出数据将其封装为Model对像
View显示层:自定义cell对象,在其中添加各种组件,并且包含了资源
Control控制层:将显示层与数据层联系,调用view层方法,设置资源
封装Cell的写法:
#import
"MovieCell.h"
@implementation MovieCell
// 覆写了父类的初始化方法
- ( instancetype )initWithStyle:( UITableViewCellStyle )style reuseIdentifier:( NSString *)reuseIdentifier{
self = [ super initWithStyle :style reuseIdentifier :reuseIdentifier];
if ( self ) {
[ self _initViews ];
}
return self ;
}
- ( void )awakeFromNib {
[ super awakeFromNib ];
[ self _initViews ];
}
// 初始化各组件
- ( void )_initViews{
// 图片
UIImageView *imgView = [[ UIImageView alloc ] initWithFrame : CGRectMake (10, 10, 100, 120)];
imgView. tag = 100;
imgView. image = [ UIImage imageNamed : _model . imgName ];
[ self . contentView addSubview :imgView];
// 标题
UILabel *titleLabel = [[ UILabel alloc ] initWithFrame : CGRectMake (120, 10, 300, 30)];
titleLabel. tag = 101;
titleLabel. textAlignment = NSTextAlignmentLeft ;
titleLabel. font = [ UIFont boldSystemFontOfSize :20];
titleLabel. textColor =[ UIColor orangeColor ];
[ self . contentView addSubview :titleLabel];
// 年份
UILabel *yearLabel = [[ UILabel alloc ] initWithFrame : CGRectMake (120, 50, 300, 20)];
yearLabel. tag =102;
yearLabel. textAlignment = NSTextAlignmentLeft ;
yearLabel. font = [ UIFont boldSystemFontOfSize :16];
[ self . contentView addSubview :yearLabel];
// 评分
UILabel *ratingLabel = [[ UILabel alloc ] initWithFrame : CGRectMake (120, 90, 300, 20)];
ratingLabel. tag =103;
ratingLabel. textAlignment = NSTextAlignmentLeft ;
ratingLabel. font = [ UIFont boldSystemFontOfSize :16];
[ self . contentView addSubview :ratingLabel];
}
@implementation MovieCell
// 覆写了父类的初始化方法
- ( instancetype )initWithStyle:( UITableViewCellStyle )style reuseIdentifier:( NSString *)reuseIdentifier{
self = [ super initWithStyle :style reuseIdentifier :reuseIdentifier];
if ( self ) {
[ self _initViews ];
}
return self ;
}
- ( void )awakeFromNib {
[ super awakeFromNib ];
[ self _initViews ];
}
// 初始化各组件
- ( void )_initViews{
// 图片
UIImageView *imgView = [[ UIImageView alloc ] initWithFrame : CGRectMake (10, 10, 100, 120)];
imgView. tag = 100;
imgView. image = [ UIImage imageNamed : _model . imgName ];
[ self . contentView addSubview :imgView];
// 标题
UILabel *titleLabel = [[ UILabel alloc ] initWithFrame : CGRectMake (120, 10, 300, 30)];
titleLabel. tag = 101;
titleLabel. textAlignment = NSTextAlignmentLeft ;
titleLabel. font = [ UIFont boldSystemFontOfSize :20];
titleLabel. textColor =[ UIColor orangeColor ];
[ self . contentView addSubview :titleLabel];
// 年份
UILabel *yearLabel = [[ UILabel alloc ] initWithFrame : CGRectMake (120, 50, 300, 20)];
yearLabel. tag =102;
yearLabel. textAlignment = NSTextAlignmentLeft ;
yearLabel. font = [ UIFont boldSystemFontOfSize :16];
[ self . contentView addSubview :yearLabel];
// 评分
UILabel *ratingLabel = [[ UILabel alloc ] initWithFrame : CGRectMake (120, 90, 300, 20)];
ratingLabel. tag =103;
ratingLabel. textAlignment = NSTextAlignmentLeft ;
ratingLabel. font = [ UIFont boldSystemFontOfSize :16];
[ self . contentView addSubview :ratingLabel];
}
//
当子视图重新布局的时候调用此方法
- (
void
)layoutSubviews{
[super layoutSubviews];
//
获取组件,赋值
UIImageView *imgview = ( UIImageView *)[ self . contentView viewWithTag :100];
imgview. image = [ UIImage imageNamed : _model . imgName ];
UILabel *titleLabel = ( UILabel *)[ self . contentView viewWithTag :101];
titleLabel. text = _model . title ;
UILabel *yearLabel = ( UILabel *)[ self . contentView viewWithTag :102];
UIImageView *imgview = ( UIImageView *)[ self . contentView viewWithTag :100];
imgview. image = [ UIImage imageNamed : _model . imgName ];
UILabel *titleLabel = ( UILabel *)[ self . contentView viewWithTag :101];
titleLabel. text = _model . title ;
UILabel *yearLabel = ( UILabel *)[ self . contentView viewWithTag :102];
yearLabel.text = _model.year;
UILabel
*ratingLabel = (
UILabel
*)[
self
.
contentView
viewWithTag
:103];
ratingLabel. text = _model . rating ;
}
// 设置数据源,同时设置属性
- ( void )setModel:( MovieModel *)model{
if ( _model != model) {
_model = model;
[ self setNeedsLayout ];
}
}
- ( void )setSelected:( BOOL )selected animated:( BOOL )animated {
[ super setSelected :selected animated :animated];
}
ratingLabel. text = _model . rating ;
}
// 设置数据源,同时设置属性
- ( void )setModel:( MovieModel *)model{
if ( _model != model) {
_model = model;
[ self setNeedsLayout ];
}
}
- ( void )setSelected:( BOOL )selected animated:( BOOL )animated {
[ super setSelected :selected animated :animated];
}
@end