iOS cell的复用以及自定义cell

2024-06-16 18:04
文章标签 cell 自定义 ios 复用

本文主要是介绍iOS cell的复用以及自定义cell,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

自定义cell以及cell复用的内容

文章目录

  • 自定义cell以及cell复用的内容
    • 前言
    • cell的复用原理
    • cell的复用的两种不同方式
    • 自定义cell的实现
    • 总结

前言

cell是我们开发中的一个重要的控件,下面来讲解一下这个内容

cell的复用原理

cell的复用是UITableView的最核心的内容,这里解释一下他的一个复用原理:

初始化的时候他会先创建cell的缓存字典 和 section的缓存array,以及一个用于存放复用cell的mutableSet(可变的集合)。并且它会去创建显示的(n+1)个cell,其他都是从中取出来重用。

当有cell滑出屏幕时,会将其放入到一个set中(相当于一个重用池),当UITableView要求返回cell的时候,datasource会先在集合中查找是否有闲置的cell,若有则会将数据配置到这个cell中,并将cell返回给UITabelView。 这大大减少了内存的开销。

因为我在滚动的过程中会出现一个将cell滚出屏幕外的时候,这时候如果我们一直创建cell的话,如果cell太多了就会出现一个内存开销过多的一个问题。所以我们要采用这个复用的方式来提高内存利用率。

在表视图显示的时候,会创建(视图中可看的单元格个数+1)个单元格,一旦单元格因为滑动的而消失在我们的视野中的时候,消失的单元格就会进入缓存池(或叫复用池),当有新的单元格需要显示的时候,会先从缓存池中取可用的单元格,获取成功则使用获取到的单元格,获取失败则重新创建新的单元格,这就是整个的复用机制。

cell的复用的两种不同方式

接下来讲一下·cell的两种复用方式,主要分成注册和非注册两种方式。

注册

- (void)viewDidLoad {[super viewDidLoad];self.tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStyleGrouped];self.tableView.delegate = self;self.tableView.dataSource = self;self.ary = @[@"头像", @"名字", @"微信号"];[self.view addSubview:_tableView];[self.tableView registerClass:[cell02 class] forCellReuseIdentifier:@"cell"]; //使用代码自定义cell// Do any additional setup after loading the view.
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {cell02* cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];return cell;
}

非注册

- (void)viewDidLoad {[super viewDidLoad];_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style: UITableViewStyleGrouped];//设置两个代理_tableView.delegate = self;_tableView.dataSource = self;[self.view addSubview:_tableView];// Do any additional setup after loading the view.
}
-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {NSString* cellStr = @"cell";UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:cellStr];if (cell == nil) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellStr];}return cell;

这两种方式都是可以实现复用的,两者有部分的区别,这里引用一段学长博客的话:

上述代码的区别在于注册方法需要提前对我们要使用的cell类进行注册,如此一来就不需要在后续过程中对我们的单元格进行判空。
这是因为我们的注册方法:

  • (void)registerClass:(nullable Class)cellClass forCellReuseIdentifier:(NSString *)identifier API_AVAILABLE(ios(6.0));
    在调用过程中会自动返回一个单元格实例,如此一来我们就避免了判空操作

区别2:

引用的方法不同

  • - (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;
  • (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);

前者用于非注册的方式,后者用于注册的方式中。在写代码的时候注意一一对应。

自定义cell的实现

我们首先要实现自定义cell需要实现两个协议:

UITableViewDelegateUITableViewDataSource

前者的主要用于实现显示单元格,设置单元格的行高和对于制定的单元格的操作设置头视图和尾视图

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section API_AVAILABLE(ios(6.0));
- (void)tableView:(UITableView *)tableView willDisplayFooterView:(UIView *)view forSection:(NSInteger)section API_AVAILABLE(ios(6.0));
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath API_AVAILABLE(ios(6.0));
- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(UIView *)view forSection:(NSInteger)section API_AVAILABLE(ios(6.0));
- (void)tableView:(UITableView *)tableView didEndDisplayingFooterView:(UIView *)view forSection:(NSInteger)section API_AVAILABLE(ios(6.0));
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;

后者主要用于设置UITableView的section和row的数量

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

我们自定义cell先要创建一个类继承UITableViewCell

#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN
@interface myCustomCell : UITableViewCell  //在这里设置我们自己需要的一些UI控件
@property (nonatomic, strong) UIButton* btn;
@property (nonatomic, strong) UILabel* label1;
@property (nonatomic, strong) UILabel* label2;
@property (nonatomic, strong) UIImageView* imageView01;
@endNS_ASSUME_NONNULL_END

然后需要重写一个方法- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier

-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];if ([self.reuseIdentifier isEqualToString:@"picture"]) {_label1 = [[UILabel alloc] init];_label1.textColor = UIColor.blackColor;_label1.font = [UIFont systemFontOfSize:17];[self.contentView addSubview:_label1];_label2 = [[UILabel alloc] init];_label2.textColor = UIColor.grayColor;_label2.font = [UIFont systemFontOfSize:10];[self.contentView addSubview:_label2];_imageView01 = [[UIImageView alloc] init]; // 创建UIImageView对象[self.contentView addSubview:_imageView01];_btn = [UIButton buttonWithType:UIButtonTypeCustom];[self.contentView addSubview:_btn];}return self;
}

最后设置一个布局

-(void)layoutSubviews {//设置一下自己ui控件的frame
}

这样就可以实现我们的一个自定义cell的内容了。

总结

这里简单介绍了一下有关自定义cell的内容和cell复用的原理。

这篇关于iOS cell的复用以及自定义cell的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1067161

相关文章

iOS HTTPS证书不受信任解决办法

之前开发App的时候服务端使用的是自签名的证书,导致iOS开发过程中调用HTTPS接口时,证书不被信任 - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAu

ROS话题通信流程自定义数据格式

ROS话题通信流程自定义数据格式 需求流程实现步骤定义msg文件编辑配置文件编译 在 ROS 通信协议中,数据载体是一个较为重要组成部分,ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty… 但是,这些数据一般只包含一个 data 字段,结构的单一意味着功能上的局限性,当传输一些复杂的数据,比如:

添加自定义的CALayer

iOS开发UI篇—CAlayer(创建图层) 一、添加一个图层 添加图层的步骤: 1.创建layer 2.设置layer的属性(设置了颜色,bounds才能显示出来) 3.将layer添加到界面上(控制器view的layer上)  1 // 2 // YYViewController.m 3 // 01-创建一个简单的图层 4 // 5 //

IOS 数组去重的几种方式

本来只知道NSSet和KeyValues的。今天又新学了几种方式 还有就是和同事学的一种方式 外层循环从0开始遍历,内层从最后一个元素开始遍历 for(int i=0;i<index;i++){  for(int j=index-1;j>i;j-- ){ } }

iOS Assertion failure in -[UITableView _classicHeightForRowAtIndexPath:]

iOS Assertion failure in -[UITableView _classicHeightForRowAtIndexPath:]  2015-04-24 11:40  956人阅读  评论(0)  收藏  举报   分类:   iOS 基础篇(208)  版权声明:本文为博主原创文章,未经博主允许不得转载。 Assertion

iOS:编译时出现no such file or directory:xxx以及use twice...filenames are used to distinguish private dec

简    注册  登录   添加关注 作者  婉卿容若 2016.04.29 11:22 写了21870字,被16人关注,获得了14个喜欢 iOS:编译时出现"no such file or directory:xxx"以及"use twice...filenames are used to distinguish private

iOS 到处 ipa包的时候 会有四个选项分别代表什么

如图 在 iOS 到处 ipa包的时候 会有四个选项  1.Save for iOS App Store Deployment 保存到本地 准备上传App Store 或者在越狱的iOS设备上使用 2.Save for Ad Hoc Deployment 保存到本地 准备在账号添加的可使用设备上使用(具体为在开发者账户下添加可用设备的udid),该app包是发布证书编

iOS 7适配上存在的各种问题

谈谈项目中遇到的各种iOS7适配问题 由于我的项目要适配到iOS7.1, 而现在已经是9时代了,在实际工作中我也是遇到了各种奇葩的坑,所以我想尽快把遇到的iOS7适配问题和解决方案分享出来,以后这些东西可能就用处不大了。   1.字体问题 iOS7中的字体适配恐怕是最麻烦的坑了,原因是iOS7以上的许多字体在7都是不存在的,甚至包括一些system-字体。比如system-

android自定义View的和FramgentActivity的一个小坑

对于自定义View //加载样式TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TitleBarView, defStyleAttr, 0);setTitle(typedArray.getString(R.styleable.TitleBarView_main_title));//不能写成

第三十七章 添加和使用自定义标题元素 - 自定义标头的继承

文章目录 第三十七章 添加和使用自定义标题元素 - 自定义标头的继承自定义标头的继承示例 在 `SOAPHEADERS` 参数中指定支持的标头元素自定义标头的继承 第三十七章 添加和使用自定义标题元素 - 自定义标头的继承 自定义标头的继承 如果创建此Web 服务的子类,该子类将继承不特定于方法的标头信息 — 包含在 <request> 或 <response> 元素中的标头信