今天学习的是UITableView的高级使用
今天主要是自定义UITableViewCell以及优化以前的写法,将给cell的赋值等封装进自定义的UITableViewCell类中,这样会很大程度提高代码的复用率,还有自适应高度的写法
1. 首先自定义UITableViewCell的步骤是:
1.创建TableViewCell的子类
2.重写初始化方法
3.把要添加的控件添加到cell的显示内容区域contentView上面
4.把系统的cell 替换成 自定义cell 完成
我们创建一个继承与UITableViewCell的子类,然后重写初始化方法:
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self addSubview];// 这是一个添加子视图的方法
}
return self;
}
添加子视图的方法:(把需要添加的子视图都写成这个类的属性好使用):
这里我们添加的属性有:
添加子视图中的创建就不写出来了
// 三个label
@property (nonatomic, retain)UILabel *nameLabel;
@property (nonatomic, retain)UILabel *genderLabel;
@property (nonatomic, retain)UILabel *phoneLabel;
// 赋值cell的model对象的属性
@property (nonatomic, retain)CellModel *model;
一个自定义的UITableViewCell就完成了,而这里的赋值cell的model对象的属性有什么用呢?这是一个用来给这个类里的控件需要根据数据来进行变化的例如label的text等赋值使用的,接下来会介绍怎样赋值.
- 以前我们给cell的赋值方法是这样的:
需要在这里进行赋值,无法使自定义的cell可以高服用
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"MyCell";
MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[[MyTableViewCell alloc] initWithStyle:
(UITableViewCellStyleSubtitle) reuseIdentifier:identifier] autorelease];;
}
CellModel *model = self.dataArray[indexPath.row];
cell.nameLabel.text = model.name;
cell.phoneLabel.text = model.phoneNumber;
cell.genderLabel.text = model.gender;
if ([model.gender isEqualToString:@"女"]) {
cell.imageV.image = [UIImage imageNamed:@"nvshen"];
}
return cell;
}
封装进类里的cell的赋值方法:
在这里我们自定义两个cell,例如一个男的和一个女的cell类;可以通过数据model中的性别来判断进行创建不同的cell,可以使tableView上的cell多元化.
/ 在给model赋值的同时 我们希望 也给cell上控件完成赋值
// cell的内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 根据model的值来判断 显示不同的cell
CellModel *model = self.dataArray[indexPath.row];
if ([model.gender isEqualToString:@"女"]) {
static NSString *identifier = @"WomanCell";
// 创建男的
MyTableViewCell *womanCell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (womanCell == nil) {
womanCell = [[[MyTableViewCell alloc] initWithStyle:
(UITableViewCellStyleSubtitle) reuseIdentifier:identifier] autorelease];
}
womanCell.model = model;
return womanCell;
}else {
static NSString *manIndentifier = @"ManCell";
// 创建女的
ManTableViewCell *manCell = [tableView dequeueReusableCellWithIdentifier:manIndentifier];
if (manCell == nil) {
manCell = [[[ManTableViewCell alloc] initWithStyle:
(UITableViewCellStyleSubtitle) reuseIdentifier:manIndentifier] autorelease];
}
manCell.manCellModel = model;
return manCell;
}
}
以上代码是怎么进行赋值的呢?在最后一步:
manCell.manCellModel = model;或者womanCell.model = model;这两个不同cell的这一相同步骤中,都调用了各自cell类中的setter的方法,这时候我们可以重写一下其类中的setter方法,以manCell为例:
这样就完成了赋值,以后只要是这个相同类型的cell可以直接拿来使用,给一个数据model就行了
// 重写model的set方法 使赋值model的同时 也对控件进行赋值
- (void)setManCellModel:(CellModel *)manCellModel {
if (_manCellModel != nil) {
[_manCellModel release];
_manCellModel = [manCellModel retain];
}
self.nameLabel.text = manCellModel.name;
}
- 一般cell的内容不定,我们可以使用自适应高度来动态适应label的高度,然后根据label的高度来改变cell的高度.
以一个字符串为例:
先创建一个label的text为字符串str
NSString *str = @"彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直至黑白彩虹直";
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 100, 300, 100)];
label.backgroundColor = [UIColor cyanColor];
label.font = [UIFont systemFontOfSize:16];
label.numberOfLines = 0;
label.text = str;
[self.view addSubview:label];
[label release];
接下来主要步骤就是:
1.计算一下字符串 所占高度
2.定值 宽度 字体大小
3.参数size 宽度填label的宽度,高度填一个最大高度(达不到的高度)
4.构建字体大小的字典
(NSFontAttributeName UIFont 再系统中的属性的名字(key))
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:[UIFont systemFontOfSize:16], NSFontAttributeName,nil];
CGRect frame = [str boundingRectWithSize:CGSizeMake(300, CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin) attributes:dic context:nil];
// 更改label的高度
CGRect temp = label.frame;
temp.size.height = frame.size.height;
label.frame = temp;
这样改变str,label可以适应其高度来改变自己的高度,既然label的高度确定了,就可以根据cell高度的方法中改变cell的高度了
- 接下来最后一个就是怎么设置点击时,可以不同状态可以设置不同的例如照片等,这时候我们可以设置一个状态属性在model这个数据类中,例如:
@property (nonatomic, assign)BOOL isSelect;
这个属性就是判断cell在哪个状态时,就设置不同状态时的照片,比如说一个cell的选中状态默认是NO状态,判断model的这个属性的值,然后在自定义的cell类中根据这个值来加载不同的照片
// 点击方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// 取出点击cell对应的model
CellModel *model = self.dataArray[indexPath.row];
// 取出被点击的cell
NewsTableViewCell *cell = (NewsTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
// 更改点击的状态
model.isSelect = !model.isSelect;
// 然后更改cell上的图片
if (model.isSelect == YES) {
cell.selectImage.image = [UIImage imageNamed:@"select"];
} else {
cell.selectImage.image = [UIImage imageNamed:@"cancel"];
}
}
自定义的cell类中根据model的状态属性值来加载不同的照片
if (newsModel.isSelect == NO) {
self.selectImage.image = [UIImage imageNamed:@"cancel"];
} else {
self.selectImage.image = [UIImage imageNamed:@"select"];
}
把这三天的UITableView的使用结合起来就可以使用UITableView写一些实用的页面出来啦.