UI学习之——cell的复用与自定义cell

一、cell的复用

        在UI中加载单元格的时候,每次加载都会创建新的cell,cell显示完后会再销毁。但是每次都销毁cell和创建新的cell会很麻烦,于是我们可以使用一个对象池,当对象池为空的时候,加载视图的时候我们创建新的cell,然后在滑动等操作使原本显示在屏幕上的cell不再显示在当前屏幕的时候,并不是对该cell进行销毁,而是将其放进对象池中,然后再加载新的cell的时候也并不是新创建一个cell,而是直接从对象池中取出一个cell对象,然后给它的相关属性赋上新的值。从而实现cell的复用,这样做的好处是可以提升程序的性能,避免你的代码因为创建太多的cell而挂掉。

        实现cell的复用有两种办法,一个是手动判空实现(即非注册的方法),一种是使用cell的注册机制。

手动(非注册):

dequeueReusableCellWithIdentifier:意思是出列的可用的cell,即使用这个方法可以获取通过滚动创建过并放回对象池中的可以复用的cell对象。

在手动实现cell的函数中,我们先创建一个局部字符串变量做为cell的id,然后使用dequeueReusableCellWithIdentifier方法在当前的UITableView对象中寻找为该id的单元格cell,这样的话我们每次调用该函数的时候都会根据这个id判断单元格有没有被创建过,如果没被创建过那么cell == nil,这时候我们就直接创建一个新的cell;反之如果不为nil则说明我们可以直接从对象池中取出现有的cell用,然后给cell赋上我们需要的相关属性,就实现了cell的复用。

例:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *strID = @"id";
    UITableViewCell *cell = [_tabView dequeueReusableCellWithIdentifier: strID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: strID];
    }
    cell.textLabel.text = @"aaa";
    return cell;
}

自动(注册):

使用cell的注册机制,在cell的复用的时候不需要判空,在viewDidLoad中先对需要复用的cell使用registerClass进行注册,然后在创建cell的函数中使用dequeueReusableCellWithIdentifier获取可复用的cell,如果没有可复用的cell,就自动利用注册cell时提供的类创建一个新的cell并返回。

例:

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *strID = @"id";
    MyTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier: strID];
    cell.backgroundColor = [UIColor redColor];
    return cell;
}

非注册和注册的区别在于:非注册时每一次使用cell的时候都需要判空,而注册的方法需要先注册要复用的cell,但不需要在获取cell的时候手动判断cell的获取是否为nil

二、自定义cell

 认识reuseIdentifier:

         reuseIdentifier是iOS开发中UITableView和UICollectionView中的一个属性。它用于标识和重用UITableViewCell和UICollectionViewCell。在滚动列表时,当一个cell离开屏幕时,它的reuseIdentifier会被系统重新标记并添加到可重用的队列中,当需要新的cell时,系统会从可重用的队列中取出一个相同reuseIdentifier的cell并进行重用,从而提高性能。在注册 UITableViewCell 时,我们需要为每种类型的 cell 提供一个 reuseIdentifier 参数,它是一个字符串类型的标识符,用于标记不同的 cell 类型。当 UITableView 需要展示某个 cell 时,它会先从内部的缓存池中查找是否有可重用的 cell,如果有的话就使用它,否则就根据 reuseIdentifier 参数创建一个新的 cell。

        总之,reuseIdentifier 参数是用于标识 UITableViewCell 的标识符,使得 UITableView 可以高效地重用它们。

        自定义cell就是自定义一个cell的模版,该模版可以为多个具有相同或者类似作用的cell初始化,这样就便于我们写代码,让我们不用每次都手动为cell初始化。

        在自定义cell的的时候,我们需要将其写在UITableViewCell的子类文件中,然后在该文件的.h文件中添加我们所需要的相关控件,然后在.m中重写一个初始化的initWithStyle:reuseIdentifier:方法,在该方法中我们重写要新建self,再使用父类super的initWithStyle:reuseIdentifier:方法初始化该self,然后为手动为该self的各个属性赋值,最后返回self。就类似于前面学的内容的重写initWithXxx方法。

        在添加当前控件到原视图上时,我们要将self做为self.contentView的子类。其中contentView是cell的subView,是内容视图,当UITableView.editing = YES时,即设置UITableView的编辑状态,那么在自定义cell中,一定要把cell的subVIew加载到contentView中

        实现完上面那个函数后,我们还需要实现一个控制其位置的函数——layoutSubviews,在该函数中我们可以设置各个控件的位置。

例:

@interface ViewController ()

@end

static NSString *str = @"id";
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView = [[UITableView alloc] init];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    self.tableView.backgroundColor = [UIColor grayColor];
    [_tableView registerClass:[MyTableViewCell class] forCellReuseIdentifier:str];
    [self.view addSubview:_tableView];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 3;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 3;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 100;
}

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MyTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:str];
    
    return cell;
}



@end
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface MyTableViewCell : UITableViewCell

@property (nonatomic, strong) UILabel *label;
@property (nonatomic, strong) UIButton *button;

@end

NS_ASSUME_NONNULL_END
#import "MyTableViewCell.h"

@implementation MyTableViewCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    self.label = [[UILabel alloc] init];
    self.label.text = @"子视图";
    [self.contentView addSubview:_label];
    self.button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    
    [self.contentView addSubview:_button];
    return self;
}

- (void)layoutSubviews {
    _label.frame = CGRectMake(0, 0, 70, 80);
    _button.frame = CGRectMake(100, 0, 70, 70);
}


@end

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值