cell的两种复用方式
对于cell复用,我们暂时先做简单了解,本篇主要为了介绍cell的使用
cell的重用机制:当我们使用tableView时,系统只会创建屏幕中显示的cell的个数+1,当cell滑出可视范围时,会将此cell放出重用池,当有新的cell滑进可视范围时,先到重用池里去找,找不到就创建,找得到就直接用,所以会用串(有时候不会串<cell的个数小于3>)
非注册
- (id) dequeueReusableCellWithIdentifier: (NSString*) identifier {
//尝试获取可以复用的单元格
//如果得不到,返回为nil
UITableViewCell* cell = [_tableView dequeueReusableCellWithIdentifier:@"iOS"] ;
}
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"iOS"];
}
注册
- (id) dequeueReusableCellWithIdentifier: (NSString*) identifier forIndexPath: (NSIndexPath*) indexPath {
[self.tableView registerClass:[TableViewCell class] forCellReuseIdentifier:@"iOS"] ;
TableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"iOS" forIndexPath: indexPath] ;
}
自定义cell实现过程
先创建UITableViewCell类文件,然后在.h文件定义并初始化所需的cell
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface TableViewCell : UITableViewCell
@property (strong, nonatomic) UILabel* label ;
@property (strong, nonatomic) UIButton* button ;
@end
NS_ASSUME_NONNULL_END
之后在.m文件实现两个必要的方法。
//在接下来实现的两个方法中,即自定义所需cell的特性 的过程
//必须实现的方法之一
- (instancetype) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier] ;
//初始化label cell
self.label = [[UILabel alloc] init] ;
[self.contentView addSubview:_label] ;
//初始化button cell
self.button = [[UIButton alloc] init] ;
[self.contentView addSubview:self.button] ;
return self;
}
//必须实现的方法之二
//此方法用来为button label等设置位置、文字、图片、风格颜色等特性
- (void) layoutSubviews {
//
_label.frame = CGRectMake(50, 50, 100, 30) ;
_label.text = @"iOS" ;
self.button.frame = CGRectMake(10, 10, 50, 50) ;
}
这样我们的自定义就完成了,然后在具体的使用如下:
在ViewController.h中签订协议并设置一个tableView来展现cell。
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
<
UITableViewDelegate,
UITableViewDataSource
>
@property (strong, nonatomic)UITableView* tableView;
@end;
之后在ViewController.m中进行进一步实现。
#import "ViewController.h"
#import "TableViewCell.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//创建数据视图
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
//设置代理
tableView.delegate = self;
tableView.dataSource = self;
//注册cell
[tableView registerClass:[TAYTableViewCell class] forCellReuseIdentifier:@"cellFirst"];
//将数据视图添加到主视图上
[self.view addSubview:_tableView];
}
//设置数据视图的组数
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
return 10;
}
//获取每组单元格的个数
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
//获取单元格高度
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 60
}
//创建单元格对象函数(创建几个单元格下面的函数就要被调用几次)
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
testTableViewCell *cellFirst = [tableView dequeueReusableCellWithIdentifier:@"cellFirst" forIndexPath:indexPath]
//设置自定义cell中按钮的信息
[cellFirst.button addTarget:self action:@selector(pressButton) forControlEvents:UIControlEventTouchUpInside];
return cellFirst;
}
//其中注册过的cell不需要判空查看是否可以复用
//注册是为某一identifier 注册一个Class
//当标识符为identifier 的Cell队列中没有可复用的cell时,系统会自动创建一个绑定的Class类型的cell,所以无需自己判空
若使用非注册的cell,可以在原来的方法中这样写:
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//这里是UITableView类,不是自定义的cell,但这里也可以使用上文的自定义的cell
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"123"];
//对cell进行判空
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"123"];
}
//
//非自定义cell自带的属性有UIImageView、UILabel等,这里用UILabel显示cell所在的行数
cell.textLabel.text = [NSString stringWithFormat:@"第%ld行", indexPath.row];
//indexPath是随方法传进来的值,可以找到当前的cell的indexPath.row与indexPath.section
return cell;
}
非自定义cell即系统提供的UITableViewCell类,里面会有已经写好的一些属性,如果是自定义cell,那么就只会有自己定义好的变量或属性。实际上自定义cell不一定需要注册,非注册也可以。那么相应地,非自定义的cell也是一样的。