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

UI一揽子计划 11 (自定义UITableViewCell、Cell 的自适应高度)

2015-09-10 12:54 507 查看
一. 自定义UITableViewCell
在日常的编程中,系统提供的几种Cell 样式 往往不能满足我们的需求.所以需要我们给它进行自定义样式.
自定义Cell 就是创建一个UITableViewCell 的子类.把Cell 上的空间都封装在子类中,简化UIViewController上的代码 .   子视图空间添加到Cell 的ContentView 上面.
Cell 中声明一个Model类型的属性,ViewController中获取到Model对象后赋值给Cell 的Model属性
Cell 中重写Model 的setter 方法 把Model对象中的内容重新赋值给各个控件.
M和V之间不直接进行通信,C负责M和V之间进行通信.
通常我们会在tableView:cellForRowAtIndexPath:⽅方法中根据不同的
Model来决定使⽤用什么类型的cell
每种类型的cell要定义不同的重⽤用标识符
cell重⽤用的时候会根据重⽤用标识从重⽤用队列中取⽤用哪种类型的cell

自定义Cell

的步骤
   1.

创建一个继承自UITableViewCell

的类
   2.

重写初始化方法
   3.

在初始化方法中
把需要的视图添加在self.contentView上面
   4.

未完待续
(在tableView上面完成的)
     

在UITableView里面把系统的UItbleViewCell

换成我们定义好的GodGirlCell

在Cell自定义中重写
- (void)setModel:(GodGirlModel

*)model

{

   
if
(_model

!= model) {

        [_model

retain];

       
_model
= [model
retain];

    }

   
self.nameLabel.text

=
self.model.name;

   
self.genderLabel.text

=
self.model.gender;

   
self.hobbyLebel.text

=
self.model.hobby;

   
self.phoneLabel.text

=
self.model.phoneNumber;
   
}
在UITableView里面把系统的UItbleViewCell

换成我们定义好的GodGirlCell

- (UITableViewCell

*)tableView:(UITableView

*)tableView cellForRowAtIndexPath:(NSIndexPath

*)indexPath
{
//    static NSString *identifiter = @"GodGirlCell";
//    GodGirlCell *cell = [tableView dequeueReusableCellWithIdentifier:identifiter];
//    if (cell == nil) {
//        cell = [[[GodGirlCell alloc]initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:identifiter]autorelease];
//    }
显示数据

1
//    GodGirlModel *godGirl = self.array[indexPath.row];
//    cell.godGirlimageview.image = [UIImage imageNamed:@"nvshen"];
//    cell.nameLabel.text =
godGirl.name;
//    cell.hobbyLabel.text = godGirl.hobby;
//    cell.phoneLabel.text = godGirl.phoneNumber;
显示数据

2
   

//
把model

传进Cell

内部进行赋值
   

//
把model进入

cell
内部

   
//
通过重写model

的set

方法

   
GodGirlModel
*godGirl =
self.array[indexPath.row];
//

利用model的属性选择

显示不同的cell

   
一个tableView

显示多种cell思路:

    1.

创建多种不同布局的cell
    2.

根据数据中特定的字段来判断要显示的哪种cell
     3.

多种
Cell
的应用场景非常广
if

([godGirl.gender

isEqualToString:@"女"])
{
       

//
显示带图片的cell

       
static
NSString
*identifiter =
@"GodGirlCell";

//
按照这个标示符
初始化这种Cell

不要重复

       
GodGirlCell
*cell = [tableView
dequeueReusableCellWithIdentifier:identifiter];

       
if
(cell ==
nil) {

            cell = [[[GodGirlCell

alloc]initWithStyle:(UITableViewCellStyleSubtitle)

reuseIdentifier:identifiter]autorelease];

        }

       
//
显示数据

        cell.model

= godGirl;

       
return
cell;

    }
else
if([godGirl.gender

isEqualToString:@"男"])
{

       
//
显示
不带图片的cell

       
static
NSString
*identifiter =
@"GodBoyCell";

       
GodBoyCell
*cell = [tableView
dequeueReusableCellWithIdentifier:identifiter];

       
if
(cell ==
nil) {

            cell = [[[GodBoyCell

alloc]initWithStyle:(UITableViewCellStyleSubtitle)

reuseIdentifier:identifiter]autorelease];

        }

        cell.model

= godGirl;

       

       
return
cell;
    }

二. Cell 的自适应高度

     1.
UILabel

*label = [[UILabel

alloc]initWithFrame:CGRectMake(30,

100,

300,

100)];

    label.backgroundColor

= [UIColor

grayColor];

    [self.window

addSubview:label];

    label.font

= [UIFont

systemFontOfSize:16];

   
NSString
*string =@"去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去去";

    label.text

= string;
    label.numberOfLines

=
0; 
计算文字的高度
    

该方法四个参数什么意思
     Size

是之前定义的label

的宽度
高度给一个到达不了的大数
     NSStringDrawingUsesLineFragmentOrigin 

按照文本的矩形区域
返回
高度
    

构建一个字体大小的字典 

字体大小的字号要跟定义Label的一样
    

最后一个 nil

该方法计算

300
宽  30

字号的Label的高度
   

NSDictionary
*dic = [NSDictionary

dictionaryWithObject:[UIFont

systemFontOfSize:16]

forKey:NSFontAttributeName];

   
CGRect
frame = [string
boundingRectWithSize:CGSizeMake(300,

100000)

options:(NSStringDrawingUsesLineFragmentOrigin)

attributes:dic

context:nil];

   
NSLog(@"%f",
frame.size.height);

    [label
release];

   
CGRect
newFrame = label.frame;

    newFrame.size.height

= frame.size.height;
    label.frame

= newFrame;

     2.
NewsCell.m
- (void)dealloc

{

    [_titleLabel

release];

    [_summaryLabel

release];

    [_model

release];

    [_myImageView

release];

    [super

dealloc];
}
- (void)setModel:(NewsModel

*)model

{

   
if
(_model

!= model) {

        [_model

release];

       
_model
= [model
retain];

    }

   
self.titleLabel.text

= model.title;

   
self.summaryLabel.text

= model.summary;

   
//
初始化的时候都走这里

   
//
防止cell被复用后状态消失

   
//
不过是创建出来的
还是按照
model
中状态标识
来选取需要的图片

   
if
(model.isSelect

==
YES) {

       
self.myImageView.image

= [UIImage

imageNamed:@"select"];

    }
else
{

       
self.myImageView.image

= [UIImage

imageNamed:@"cancel"];

    }

   
CGRect
newFrame =
self.summaryLabel.frame;

    newFrame.size.height

= [NewsCell

cellWithModel:model];

   
self.summaryLabel.frame

= newFrame;

}

- (instancetype)initWithStyle:(UITableViewCellStyle)style
reuseIdentifier:(NSString

*)reuseIdentifier

{

   
self
= [super

initWithStyle:style

reuseIdentifier:reuseIdentifier];

   
if
(self) {

        [self

addSubViews];

    }

   
return
self;

}

- (void)addSubViews

{

   
self.titleLabel

= [[UILabel

alloc]initWithFrame:CGRectMake(10,

10,

330,

40)];

   
self.titleLabel.backgroundColor

= [UIColor

redColor];

   
self.titleLabel.numberOfLines

=
0;

   
self.titleLabel.font

= [UIFont

systemFontOfSize:16];

    [self.contentView

addSubview:self.titleLabel];

    [_titleLabel

release];

   

   
//
写一个imageView

   
self.myImageView

= [[UIImageView

alloc]initWithFrame:CGRectMake(350,

10,

20,

20)];

   
self.myImageView.image

= [UIImage

imageNamed:@"cancel"];

    [self.contentView

addSubview:self.myImageView];

    [_myImageView

release];

   

   
self.summaryLabel

= [[UILabel

alloc]initWithFrame:CGRectMake(10,

20
+
self.titleLabel.frame.size.height,

350,

130)];

   
self.summaryLabel.numberOfLines

=
0;

   
self.summaryLabel.font

= [UIFont

systemFontOfSize:16];

   
self.summaryLabel.backgroundColor

= [UIColor

grayColor];

    [self.contentView

addSubview:self.summaryLabel];

    [_summaryLabel

release];

}

//

通过一个字符串
返回一个高度

+ (CGFloat)cellWithModel:(NewsModel

*)model

{

   
//
计算字符串的高度

   
NSString
*string = model.summary;

   
NSDictionary
*dic =[NSDictionary

dictionaryWithObject:[UIFont

systemFontOfSize:16]

forKey:NSFontAttributeName];

   
CGRect
frame = [string
boundingRectWithSize:CGSizeMake(350,

1000000)

options:(NSStringDrawingUsesLineFragmentOrigin)

attributes:dic

context:nil];
   

return
frame.size.height;
}

NewsModel.m 
- (void)dealloc

{

    [_title

release];

    [_summary

release];

    [super

dealloc];

}
//

防崩赋值方法

- (void)setValue:(id)value
forUndefinedKey:(NSString
*)key

{
   

RootViewController.m
//

数据准备

- (void)setUpData

{

   
NSString
*path = [[NSBundle

mainBundle]

pathForResource:@"NewsData"

ofType:@"plist"];

   
NSDictionary
*plistDic = [NSDictionary

dictionaryWithContentsOfFile:path];

   
NSArray
*newsArray = [plistDic
objectForKey:@"news"];

   
//
数组一定要初始化

   
self.dataArray

= [NSMutableArray

array];

   
for
(NSDictionary

*dic
in
newsArray) {

       
NewsModel
*model = [[NewsModel

alloc]init];

        model.isSelect

=
NO;

        [model
setValuesForKeysWithDictionary:dic];

        [self.dataArray

addObject:model];

       

        [model
release];

    }

   
NSLog(@"%@",

self.dataArray);

}

- (void)addTableView

{

   
UITableView
*tableView = [[UITableView

alloc]initWithFrame:[UIScreen

mainScreen].bounds 

style:(UITableViewStylePlain)];

    tableView.delegate

=
self;

    tableView.dataSource

=
self;

    [self.view

addSubview:tableView];

    [tableView
release];

}

- (NSInteger)tableView:(UITableView

*)tableView numberOfRowsInSection:(NSInteger)section

{

   
return
self.dataArray.count;

}

- (UITableViewCell

*)tableView:(UITableView

*)tableView cellForRowAtIndexPath:(NSIndexPath

*)indexPath

{

   
static
NSString
*identifiter =
@"cell";

   
NewsCell
*cell = [tableView
dequeueReusableCellWithIdentifier:identifiter];

   
if
(cell ==
nil) {

        cell = [[NewsCell

alloc]initWithStyle:(UITableViewCellStyleSubtitle)

reuseIdentifier:identifiter];

    }

   
NewsModel
*model = [self.dataArray

objectAtIndex:indexPath.row];

    cell.model

= model;

   
return
cell;

}

- (CGFloat)tableView:(UITableView

*)tableView heightForRowAtIndexPath:(NSIndexPath

*)indexPath

{

   
//
取出model

调用cellWithModel

方法得到高度

   
NewsModel
*model = [self.dataArray

objectAtIndex:indexPath.row];

   
CGFloat
SummaryHeight = [NewsCell

cellWithModel:model];

   
return
20
+
20
+
40
+ SummaryHeight +
20;

}

//

点击触发的方法

- (void)tableView:(UITableView

*)tableView didSelectRowAtIndexPath:(NSIndexPath

*)indexPath

{

   
//
获取要点击的Cell

   
//
下面方法是获取自定义cell的方法

   
NewsCell
*cell = (NewsCell

*)[tableView
cellForRowAtIndexPath:indexPath];

   
//
不是自定义方法
就如下写

   
//UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

   
NewsModel
*model = [self.dataArray

objectAtIndex:indexPath.row];

   
//
通过model的状态

更改图片

   
//
改变model的状态

    model.isSelect

= !model.isSelect;

   
if
(model.isSelect

==
YES) {

        cell.myImageView.image

= [UIImage

imageNamed:@"select"];

    }
else
{

        cell.myImageView.image

= [UIImage

imageNamed:@"cancel"];

    }

   
NSLog(@"%d",
model.isSelect);

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