您当前的位置: 首页 >  ui

white camel

暂无认证

  • 2浏览

    0关注

    442博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

white camel 发布时间:2017-08-14 16:26:23 ,浏览量:2

使用纯代码的方式自定义等高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 

@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
效果如下图:

关注
打赏
1661428283
查看更多评论
立即登录/注册

微信扫码登录

0.0384s