博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS开发之自定义UITableViewCell
阅读量:6077 次
发布时间:2019-06-20

本文共 11144 字,大约阅读时间需要 37 分钟。

hot3.png

等高的Cell

一、storyboard方式

  1. 创建一个继承自UITableViewCell的子类

    022740_2FXA_1011331.png

  2. 在storyboard中

    - 往cell里面增加需要用到的子控件

        022934_6u0o_1011331.png

      - 设置cell的重用标识

        023022_47ed_1011331.png

     - 设置cell的class为我刚才创建的那个Cell类型XXDealCell

    023212_fVHQ_1011331.png

    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

  1. 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"];    }

转载于:https://my.oschina.net/shenhuniurou/blog/638908

你可能感兴趣的文章
C++ 多态的实现原理与内存模型
查看>>
Windows 7 x64环境下SDK Manager闪退的解决方法
查看>>
WPF的ComboBox简单用法
查看>>
HTTP协议具体解释
查看>>
解决Android Graphical Layout 界面效果不显示
查看>>
支持FreeMarker需要哪些JAR包?
查看>>
DataTables warning : Requested unknown parameter '5' from the data source for row 0
查看>>
android studio上代码编译调试中遇到的一些异常记录
查看>>
HDFS 安全模式的理解
查看>>
Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem K. UTF-8 Decoder 模拟题
查看>>
OTL翻译(7) -- otl_exception类
查看>>
hashmap理解总结
查看>>
Linux环境安装MySQL数据库(RPM格式的软件包)
查看>>
Android从源码看ListView的重用机制
查看>>
【iCore4 双核心板_ARM】例程三十三:SD_IAP_ARM实验——更新升级STM32
查看>>
Hadoop Streaming Made Simple using Joins and Keys with Python « All Things Hadoop
查看>>
二手房中介带看技巧
查看>>
非归档数据文件offline的恢复
查看>>
《裸辞的程序猿漂流记十三》——奔跑在逆袭的路上
查看>>
第三范式
查看>>