UI 一一 自定义等高cell (XIB方式)

使用纯代码的方式自定义等高cell的两种方式(Frame,Autolayout)

已经在我的这两篇博客中介绍:   

UI 一一 自定义等高cell (纯代码-Frame)方式   和   

UI 一一 自定义等高cell (纯代码-Autolayout)方式

接下来继续搞自定义等高cell,通过xib的方式,再后来就是使用storyboard的方式了.是不是感觉好多.

其实并不多.实际开发中掌握一种适合自己的就行.因为这些方式的思路和代码几乎相同!

效果图都是一样的:


实现思路及简要过程:

新建一个继承自UITableViewCell的子类,比如ZYTgCell

@interface ZYTgCell : UITableViewCell
@end

新建一个xib文件(文件名最好跟类名一致,比如ZYTgCell.xib)

  • 修改cell的class为ZYTgCell


  • 绑定循环利用标识


  • 添加子控件,设置子控件约束


  • 将子控件连线到类扩展中
@interface ZYTgCell()
@property (weak, nonatomic) IBOutlet UIImageView *iconImageView;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UILabel *priceLabel;
@property (weak, nonatomic) IBOutlet UILabel *buyCountLabel;
@end

在ZYTgCell.h文件中提供一个模型属性,比如ZYTg模型

@class ZYTg;

@interface ZYTgCell : UITableViewCell
/** 团购模型数据 */
@property (nonatomic, strong) ZYTg *tg;
@end

在ZYTgCell.m中重写模型属性的set方法

  • 在set方法中给子控件设置模型数据
- (void)setTg:(ZYTg *)tg
{
    _tg = tg;

    // .......
}

在控制器中

  • 注册xib文件
[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([ZYTgCell class]) bundle:nil] forCellReuseIdentifier:ID];
  • 给cell传递模型数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 访问缓存池
    ZYTgCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

    // 设置数据(传递模型数据)
    cell.tg = self.tgs[indexPath.row];

    return cell;
}

这里有些注意点:

1. 我们之前使用纯代码方式来自定义cell的时候,注册文件使用的是这个方法:

[self.tableView registerClass:[ZYTgCell class] forCellReuseIdentifier:ID];


使用xib创建cell的时候使用的是这个方法:

[self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([ZYTgCell class]) bundle:nil] forCellReuseIdentifier:ID];


为什么不可以使用上面的注册方法呢?

因为使用上面的那个注册方法,当缓存池中没有可用的cell的时候,就会自己去创建cell,创建cell的时候,就会调用调用initWithStyle这个方法,

这个方法是用来创建子控件,并设置子控件的一些初始化值.而我们是通过创建xib文件的方法创建子控件,所以根本不会使用到这个方法.

所以我们要使用下面的方法来注册,实现优化cell.


2. 在xib文件中,一般在identifier中绑定重用标识.


具体实现代码如下: 

ZYTg 文件

// 注意: ZYTg模型中,不需要再把字典中的数据,传到这个数据模型中,

因为我们使用了第三方框架MJExtension,这个框架中有需要快速转成模型的方法.使用这个框架会方便很多.

它会自动加载plist中的数据,并赋值给数据模型.

@interface ZYTg : NSObject

/** 图标 */
@property (nonatomic, copy) NSString *icon;

/** 标题 */
@property (nonatomic, copy) NSString *title;

/** 价格 */
@property (nonatomic, copy) NSString *price;

/** 购买数 */
@property (nonatomic, copy) NSString *buyCount;

@end

@implementation ZYTg

@end

ZYTgCell.xib文件




ZYTgCell文件


#import <UIKit/UIKit.h>

@class ZYTg;
@interface ZYTgCell : UITableViewCell

/** ZYTg模型 */
@property(nonatomic,strong)ZYTg * tg;

@end

#import "ZYTg.h"

@interface ZYTgCell ()

@property (weak, nonatomic) IBOutlet UIImageView *iconImageView;

@property (weak, nonatomic) IBOutlet UILabel *titleLabel;

@property (weak, nonatomic) IBOutlet UILabel *priceLabel;

@property (weak, nonatomic) IBOutlet UILabel *buyCountLabel;

@end

@implementation ZYTgCell

// 重写set方法,设置数据
- (void)setTg:(ZYTg *)tg
{
    _tg = tg;
    self.iconImageView.image = [UIImage imageNamed:tg.icon];
    self.titleLabel.text = tg.title;
    self.priceLabel.text = [NSString stringWithFormat:@"¥%@",tg.price];
    self.buyCountLabel.text = [NSString stringWithFormat:@"%@人已购买",tg.buyCount];
    
}

@end



ViewController 文件

#import "ViewController.h"
#import "ZYTgCell.h"
#import "ZYTg.h"
#import "MJExtension.h"

@interface ViewController ()

/** 所有的团购数据 */
@property (nonatomic, strong) NSArray *tgs;

@end

@implementation ViewController

// 使用第三方框架加载plist数据
- (NSArray *)tgs
{
    if (_tgs == nil) {
        _tgs = [ZYTg mj_objectArrayWithFilename:@"tgs.plist"];
    }
    return _tgs;
}

NSString *ID = @"tg";
- (void)viewDidLoad {
    [super viewDidLoad];
 
    self.tableView.rowHeight = 80;
    
    //这种方法不会实现优化,因为最终转换为initWithStyle,通过xib的方式创建cell,不会调用initWithStyle方法
//    [self.tableView registerClass: [ZYTgCell class]forCellReuseIdentifier:ID];
    
    // 注册的方法(优化)
    [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([ZYTgCell class]) bundle:nil] forCellReuseIdentifier:ID];
    
}

// 隐藏状态栏
- (BOOL)prefersStatusBarHidden
{
    return YES;
}

#pragma -mark 数据源方法

/** 有多少行数据 */
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.tgs.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 创建一个重用标识
    // 访问缓存池
//    static NSString *ID = @"tg";
    ZYTgCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    // 判断缓存池中是否空的,如果为空就创建
//    if (cell == nil) {
//        // 在xib中的identifier中设置标识为tg,就可以在缓存池中取到重用的cell
//        cell = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([ZYTgCell class]) owner:nil options:nil] lastObject];
//    }
    
    // 设置数据(传递数据模型)
    cell.tg = self.tgs[indexPath.row];
    
    return cell;
}

@end

比如又有一个需求:

不同类型的cell共存.也就是说在一个UITableView中显示不同类型的cell.

要实现这种需求: 

1. 就需要再创建一个继承UITableViewCell的子类,比如叫ZYTestCell

2. 再创建一个xib文件,并设置class为ZYTestCell.

3. 设置标识

4. 在控制器的方法中来根据indexPath.row 行号来使用这个cell. 

这样就实现了等高且不同类型的cell同时出现在UITableView中.其实这种需求也是有的.

比如你在手机上看网易新闻的时候,突然加载一段广告,这个广告也在UITableView上显示,其实就是一个不同类型的cell.


具体代码(我把上面的代码稍作修改)

ViewController 文件

#import "ViewController.h"
#import "ZYTgCell.h"
#import "ZYTg.h"
#import "MJExtension.h"
#import "ZYTestCell.h"

@interface ViewController ()

/** 所有的团购数据 */
@property (nonatomic, strong) NSArray *tgs;

@end

@implementation ViewController

// 使用第三方框架加载plist数据
- (NSArray *)tgs
{
    if (_tgs == nil) {
        _tgs = [ZYTg mj_objectArrayWithFilename:@"tgs.plist"];
    }
    return _tgs;
}

NSString *tgID = @"IDtg";
NSString *testID = @"testTg";
- (void)viewDidLoad {
    [super viewDidLoad];
 
    self.tableView.rowHeight = 80;
    
    //这种方法不会实现优化,因为最终转换为initWithStyle,通过xib的方式创建cell,不会调用initWithStyle方法
//    [self.tableView registerClass: [ZYTgCell class]forCellReuseIdentifier:ID];
    
    // 注册的方法(优化)
    [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([ZYTgCell class]) bundle:nil] forCellReuseIdentifier:tgID];
    
    [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([ZYTestCell class]) bundle:nil] forCellReuseIdentifier:testID];
    
}

// 隐藏状态栏
- (BOOL)prefersStatusBarHidden
{
    return YES;
}

#pragma -mark 数据源方法

/** 有多少行数据 */
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.tgs.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 奇数cell显示TgCell,偶数行cell显示TestCell
    if (indexPath.row % 2 == 0) {
        
        ZYTgCell *cell = [tableView dequeueReusableCellWithIdentifier:tgID];
        cell.tg = self.tgs[indexPath.row];
        return cell;
    }else{
        ZYTestCell *cell = [tableView dequeueReusableCellWithIdentifier:testID];
        return cell;
    }
    
    
    
}

@end

效果如下图:













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

white camel

感谢支持~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值