关山初度尘未洗,策马扬鞭再奋蹄!这篇文章主要讲述iOS小技能:cell的重用原理及自定义cell相关的知识,希望能为你提供帮助。
【iOS小技能(cell的重用原理及自定义cell)】
引言ios开发中,要实现表格数据展示,做常用的做法就是使用UITableView。
IUITableViewCell的简介1.1 cell的结构UITableView的每一行都是一个UITableViewCell
- cell的初始化: 通过datasource的tableView: cellForRowAtIndexPath: 方法来初始化每一行
- UITableViewCell内部有一个默认的自视图ContentView :
1.2 cell的重用原理
- 重用原理
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
// 1.定义一个cell的标识
static NSString *ID = @"mjcell";
// 2.从缓存池中取出cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
// 3.如果缓存池中没有cell
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
// 4.设置cell的属性...
return cell;
- 单元格循环引用概念
- new一个xib文件来描述一个View的内部结构
- new一个自定义的视图类(继承自xib根对象的class),类名通常与xib文件名保存一致
- 将xib中的控件与自定义视图类的.m文件建立连线 (建立连线之前,对根对象的class指定为刚刚新建的控件-> 在xi b属性面板指定可重用标识符
- 提供一个类方法,返回一个创建好的自定义视图类(屏蔽从xib加载的过程)
III delegate父控件(视图控制器)监听子控件的事件,当子控件发生某些事情的时候,通知父控件工作--备注:父控件通知子控件工作,直接调用子控件的方法即可。
如果使用强引用,将造成循环的强引用--> 儿子只能对父亲进行弱引用。
@property (nonatomic,weak) id< HSGroupBuyingFooterViewDelegate> delegate; //在oc中,只有没有强用的时候,才会被立即释放;一旦自定义视图称为视图控制器的视图包含,极自定义视图为视图控制器的儿子时,且视图控制器为自定义视图(儿子)的代理,此时如果代理是强引用,将造成循环的强引用,”你中有我,我中有你“。--永远呆在内存
3.1 delegate的使用场合
- 对象A内部发生了一些事情,想通知对象B,对象A想传递数据给对象B
- 对象B想监听对象A内部发生了什么事情
- 对象A想在自己的方法内部调用对象B的某些方法,并且对象A不能对对象B有耦合依赖
- 搞清楚谁 是谁的 delegate
- 定义代理协议(协议名称的命名规范:控件类名+Delegate)
- 定义代理方法:
*代理方法名称都以空间名开头;代理方法至少有个参数,用于将控件本事传递出去
4. 设置代理对象(代理对象遵守协议,并实现协议方法)
5. 在恰当的时刻调用delegate的协议方法,来通知delegate发生了什么事情(在调用之前判断代理是否实现了该代理方法)
IV 通过代码自定义cell
- new一个继承自UITableViewCell的类
- 重写initWithStyle: reuseIndentifier: 方法(对子控件的属性进行一次性赋值)
3. 并添加需要显示的子控件到contentView中
4. 提供数据模型、frame模型
数据模型用于存放文字、图片数据;frame模型存放数据模型、所有子控件的frame、cell的高度
5. cell拥有一个frame模型
6. 重写frame模型的setter方法(设置子控件的显示数frame);对frame的对象实例化采用懒加载方法,即进行getter方法的重写
//
//HSStatusCell.h
#import < UIKit/UIKit.h>
#import "HSStatus.h"
@interface HSStatusCell : UITableViewCell
//自定义视图的现实的数据来源于模型,即使用模型装配自定义视图的显示内容
@property (nonatomic,strong) HSStatus *status; //视图对应的模型,是视图提供给外界的接口
/**
通过数据模型设置视图内容,可以让视图控制器不需要了解视图的细节
*/
+ (instancetype) tableVieCellwWithStatus:(HSStatus *) status tableView:(UITableView *)tableView; //使用类方法获取自定义视图,参数用于视图的数据装配
//
+ (instancetype) tableVieCellwWittableView:(UITableView *)tableView; //使用类方法获取自定义视图
@end
- 设置位置
- (void)setStatus:(HSStatus *)status
_status = status;
[self settingData];
//设置位置
[self settingFrame];
- (void) settingData
//设置位置
[self.textViewsetText:self.status.text];
[self.nameView setText:self.status.name];
[self.iconView setImage:self.status.iconImage];
if (self.status.picture.length > 0)
[self.pictureView setImage:self.status.pictureImage];
[self.pictureView setHidden:NO];
else
[self.pictureView setImage:nil]; //没有配图的时候,清空图片信息--cell重用的时候,对于可选视图要进行处理
[self.pictureView setHidden:YES];
if (self.status.vip)
[self.vipView setImage:self.status.vipImage];
[self.vipView setHidden:NO]; //显示VIP视图
[self.nameView setTextColor:[UIColor redColor]];
else
[self.vipView setImage:nil]; //不是VIP的时候,清空VIP标识--cell重用的时候,针对可选视图进行特殊处理
[self.vipView setHidden:YES];
[self.nameView setTextColor:[UIColor blackColor]];
/**
设置位置信息
*/
- (void) settingFrame
//定义间距
CGFloat padding =10;
CGFloat iconX = padding;
CGFloat iconY = padding;
CGFloat iconWidth = 30;
CGFloat iconHeiht = 30;
[self.iconView setFrame:CGRectMake(iconX, iconY, iconWidth, iconHeiht)];
//设置昵称,昵称的大小由文字的长度决定
/**
1.boundingRectWithSize 方法计算给定文本所占用的区域
2.options: 计算多行的的准确高度需要传入NSStringDrawingUsesLineFragmentOrigin
3、attributes 指定字体相关属性;UIKit框架中的第一个头文件NSAttributedString.h
*/
NSDictionary *nameDict = @NSFontAttributeName:KnameFont;
CGRect nameFrame = [self.status.name boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:nameDict context:nil]; //返回一个x,y,都为0 的CGRect
nameFrame.origin.x = CGRectGetMaxX(self.iconView.frame)+padding;
nameFrame.origin.y = padding+(CGRectGetHeight(self.iconView.frame)-CGRectGetHeight(nameFrame))*0.5;
[self.nameView setFrame:nameFrame];
//设置VIP标识的frame
[self.vipView setFrame:CGRectMake(CGRectGetMaxX(self.nameView.frame)+padding, CGRectGetHeight(self.nameView.frame), 14, 14)];
//设置文本内容的frame
NSDictionary推荐阅读
- 微服务从代码到k8s部署应有尽有系列(十一日志收集)
- Vshpere零散概念补充
- Gradle基础 | 自定义插件并上传到JitPack
- 《深入浅出Vue.js》读书笔记1-Object的变化侦测
- 《深入浅出Vue.js》读书笔记2-Proxy的自我尝试
- 草系前端是如何筹备第一个b站视频的(!努力写个稿子吧)
- k8s—pod基础
- Tomcat Session管理分析面试+工作
- k8s—pod进阶(资源限制,健康检查)