UITableView是iOS开发中不可或缺的一部分,它是苹果iOS SDK提供的一种用于展示数据列表的视图控件。我们对其中的cell进行自定义,即可得到我们需要的UI界面
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
3.选择行的方法,didSelectRowAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
4.删除行的方法 :
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
创建一个TableView我们首先需要加入
协议。其中UITableViewDataSource
协议用来设置cell的行数列数。UITableViewDelegate
协议用来设置cell的相关高度。
随后在.m文件中将TbaleView的委托对象和数据源对象设为自己。
_tableView.delegate = self;
_tableView.dataSource = self;
必须要实现的方法有如下几种:
//分区的行数
- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 行数;
}
//列数
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 分区数;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 单元格高度;
}
//单元格样式,也是自定义cell需要修改的地方。
-(UITableViewCell*)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *str = @"cell";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:str];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:str];
}
return cell;
}
剩余功能在项目中总结。
cell的复用方式有两种,注册和非注册,此处给出代码来区分二者。
注册:
//注册
- (void)viewDidLoad
{
[super viewDidLoad];
//使用Nib注册cell
[self.tableView registerNib:[UINib nibWithNibName:@"CustomCell" bundle:nil] forCellReuseIdentifier:@"myCell"];
// 使用代码注册cell
[self.tableView registerClass:[CustomCell class] forCellReuseIdentifier:@"myCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identif = @"mycell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
return cell;
}
非注册:
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *str = @"cell";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:str];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:str];
}
return cell;
}
注册与非注册相比,需要在viewDidLoad中先对cell类进行注册,并且在其后的使用中不需要判空。
这是因为通过注册方法(如registerClass:forCellReuseIdentifier:或registerNib:forCellReuseIdentifier:)将指定的单元格类或Nib文件与标识符关联起来。通俗来讲,即表格视图已经知道要用哪个cell。
而在非注册的方式中,表格视图并不知道需要使用哪个单元格类或Nib文件。因此每次使用前都需要进行判空操作,这是必要的。
iOS内部使用了三个容器 _cachedCells, availableCells, _reusableCells 完成了 Cell 的复用。
重用优先级是先检查 reusableCells,然后才是 cachedCells 中的缓存。
简而言之,一开始出现的单元格和与其对应的键值对indexPath储存在cachedCells中。拷贝一份到availableCells中,当有单元格出现在视图时,先检查reusableCells中有没有可以复用的单元格,没有则新建一个单元格,并把顶部划出视图的单元格加入进reusableCells。
先给出效果:
其中的每一栏就是一个自定义cell,下面给出实现方法:
创建一个继承与UITableViewCell的myCell。
@interface myCell : UITableViewCell
@property (nonatomic, strong) UIButton *Btn;
@property (nonatomic, strong) UILabel *label1;
@property (nonatomic, strong) UIImageView * imageView1;
@end
然后在.m文件中,我们改写两个方法:
-(instancetype) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
_imageView1 = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 20, 20)];
_imageView1.image = [UIImage imageNamed:@"头像.jpeg"];
[self.contentView addSubview:_imageView1];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotice:) name:@"notice" object:nil];
_label1 = [[UILabel alloc] init];
_label1.text = @"笙";
_label1.textColor = [UIColor blackColor];
_label1.backgroundColor = [UIColor clearColor];
_label1.font = [UIFont systemFontOfSize:25];
[self.contentView addSubview:_label1];
return self;
}
-(void)layoutSubviews
{
[super layoutSubviews];
CGFloat screenWidth = UIScreen.mainScreen.bounds.size.width;
_label1.frame = CGRectMake(100, 10, screenWidth, 90);
_imageView1.frame = CGRectMake(10, 10, 80, 80);
}
@end
其中:-(instancetype) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
方法是修改cell的样式
-(void)layoutSubviews
是修改布局视图。
我们还可以根据index的不同分区列,在同一分区创建不同的的cell。这点在后续的博客中会记录。
以上就是笔者学习的自定义cell和cell的复用有关内容,多写代码,不断遇到bug,才会有更深入的理解。