UITableView 高级

来源:互联网 发布:起飞了是什么网络意思 编辑:程序博客网 时间:2024/05/21 23:32

自定义Cell

1.创建UITableViewCell的子类

2.将添加到UITableViewCell的子视图设置为属性 同时将数据类也作为属性 方便给子视图进行赋值

#import <UIKit/UIKit.h>#import "CellModel.h"@interface NewsTableViewCell : UITableViewCell@property (nonatomic ,retain) UILabel *titleLabel;@property (nonatomic, retain) UILabel *summaryLabel;// 选中图片@property (nonatomic, retain) UIImageView *imageV;@property (nonatomic, retain) CellModel *model;@end

3.重写自定义初始化方法

- (instancetype) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];    if (self) {        [self addLabel];    }    return self;}// 添加子视图- (void)addLabel{    self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake((kScreenWidth - 300) / 2, 20, 300, 40)];    self.titleLabel.backgroundColor = [UIColor orangeColor];    self.titleLabel.numberOfLines = -1;    self.titleLabel.font = [UIFont systemFontOfSize:16];    // 注意给UITableViewCell及其子类添加子视图时 需要添加到self.contentView上    [self.contentView addSubview:self.titleLabel];    [_titleLabel release];    self.summaryLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.titleLabel.left, self.titleLabel.bottom + 10, self.titleLabel.width, self.titleLabel.height)];    self.summaryLabel.backgroundColor = [UIColor grayColor];    // 多行显示    self.summaryLabel.numberOfLines = -1;    // 设置字体大小    self.summaryLabel.font = [UIFont systemFontOfSize:16];    [self.contentView addSubview:self.summaryLabel];    [_summaryLabel release];    self.imageV = [[UIImageView alloc] initWithFrame:CGRectMake(340, self.titleLabel.top + 5, 30, 30)];    [self.contentView addSubview:self.imageV];    [_imageV release];}

4.重写model属性的setter方法

- (void)setModel:(CellModel *)model{    if (_model != model) {        [_model release];        _model = [model retain];    }    // 在给model赋值的同时 给子视图进行赋值    self.titleLabel.text = model.title;    self.summaryLabel.text = model.summary;    // 在赋值的同时 改变label的高度(见下文)    // 获取字符串高度    CGFloat summaryHeight = [NewsTableViewCell cellHeightForModel:model];    // 改变一下label的高度    self.summaryLabel.height = summaryHeight;}

5.在添加cell的方法中用该类初始化对象cell

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    static NSString *identifier = @"MyCell";    NewsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];    if (cell == nil) {        cell = [[[NewsTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier] autorelease];    }    CellModel *model = self.arrData[indexPath.row];    // 直接赋值 将具体赋值过程封装在NewsTableViewCell类中进行    cell.model = model;    return cell;}

计算字符串完全显示需要的高度

用于改变存放字符串的label的高度, 通常在UITableViewCell的子类中实现

// 计算字符串的高度(类方法)+ (CGFloat)cellHeightForModel:(CellModel *)model{    // 创建字体大小的字典    // 这里设置了字体大小后 需要label的font属性做相应的改变    NSDictionary *fontDic = @{NSFontAttributeName: [UIFont systemFontOfSize:16]};    CGRect textRect = [model.summary boundingRectWithSize:CGSizeMake(300, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:fontDic context:nil];    return textRect.size.height;}

当然 不光要改变label的高度 同时需要改变cell的高度

// 行高- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{    CellModel *model = self.arrData[indexPath.row];    CGFloat tempHeight = [NewsTableViewCell cellHeightForModel:model];    // 上边距 + tilteLabel + 中间距离 + summaryLabel + 下边距    return 20 + 40 + 10 + tempHeight + 20;}

点击cell 改变cell上的子视图

给cell 添加一个UIImageView 点击cell时 UIImageView.image 变成选中图片 再次点击cell 时UIImageView.image 变回未选中图片

当然不能直接在方法中更改图片 这样子再次点击无法变回未选中图片

因此需要给model添加 isSelected 属性 来记录对应的cell的点击状态

在tableView 用 CellModel 类 “获取” 数据文件的字典数据的同时 应该给model.isSelected属性赋一个初值 而cell一开始应该显示未选中图片 所以:model.isSelect = NO;

- (void)setUpData{    NSString *path = [[NSBundle mainBundle] pathForResource:@"NewsData" ofType:@"plist"];    NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:path];    NSArray *values = dic[@"news"];    self.arrData = [NSMutableArray array];       for (int i = 0; i < values.count; i++) {          CellModel *model = [[CellModel alloc] init];          [model setValuesForKeysWithDictionary:values[i]];           ***model.isSelect = NO;***          [self.arrData addObject:model];          [model release];    }}

当然此时为了使cell在程序运行开始时呈现未选中图片 需要在给cell.model 赋值的同时 给 imageView添加一个图片 但是并不是直接给他一张未选中图片 如果这样做了 那么从重用集合中取出的cell即使是选中状态 也会在 重新赋值时变回未选中状态

我们不想在屏幕上滑时出现这样的问题 所以需要在赋值过程中判断一下(赋值过程当然还在cell的子类中进行)

- (void)setModel:(CellModel *)model{    if (_model != model) {        [_model release];        _model = [model retain];    }    // 利用model中的点选状态 解决cell复用的问题    // 需要每次被复用的cell 再进行一次与状态对应的赋值    if (model.isSelect == YES) {        self.imageV.image = [UIImage imageNamed:@"select"];    }else{        self.imageV.image = [UIImage imageNamed:@"cancel"];    }}

在点击方法中根据选中属性model.isSelect 来给cell 的 ImageView 更换图片

// cell 点击的方法- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{    // 取出被点击的cell    // 更改cell 图片    NewsTableViewCell *cell = (NewsTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];    CellModel *model = self.arrData[indexPath.row];    // 更改点击的状态    model.isSelect = !model.isSelect;    if (model.isSelect == YES) {        cell.imageV.image = [UIImage imageNamed:@"select"];    }else{        cell.imageV.image = [UIImage imageNamed:@"cancel"];    } }
0 0
原创粉丝点击