框架
- CALayer 基于 QuartzCore 框架
- UIView 基于 UIKit 框架
父类
- CALayer继承自NSObject
- UIView继承自UIResponder
小结
因为UIView
继承UIResponder
,而UIResponder
是拥有touches
事件的,说明UIView
能处理用户的触摸事件的,反之CALayer
是不能处理事件的(但是可以通过对应的方法实现),由于CALayer不需要处理交互事件、所以是轻量级的、性能要比UIView高。
CALayer添加点击事件
- 通过 touchesBegan: withEvent 方法,监听屏幕点击事件,在这个方法中通过 convertPoint 找到点击位置,进行判断,如果点击了 layer 视图内坐标,就触发点击事件
- 通过 hitTest方法找到包含坐标系的 layer 视图
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// 方法一,通过 convertPoint 转为为 layer 坐标系进行判断
CGPoint point = [[touches anyObject] locationInView:self.view];
CGPoint redPoint = [self.redLayer convertPoint:point fromLayer:self.view.layer];
if ([self.redLayer containsPoint:redPoint]) {
NSLog(@"点击了calayer");
}
// 方法二 通过 hitTest 返回包含坐标系的 layer 视图
CGPoint point1 = [[touches anyObject] locationInView:self.view];
CALayer *layer = [self.view.layer hitTest:point1];
if (layer == self.redLayer) {
NSLog(@"点击了calayer");
}
}
代码验证
- (void)viewDidLoad {
[super viewDidLoad];
self.aView = [[UIView alloc] init];
self.aLayer = [[CALayer alloc] init];
//比较UIView对象个CALayer对象在内存中的大小
NSLog(@"self.aView对象实际需要的内存大小: %zd", class_getInstanceSize([self.aView class]));//480
NSLog(@"self.aView对象实际分配的内存大小: %zd", malloc_size((__bridge const void *)(self.aView)));//480
NSLog(@"self.aLayer对象实际需要的内存大小: %zd", class_getInstanceSize([self.aLayer class]));//24
NSLog(@"self.aLayer对象实际分配的内存大小: %zd", malloc_size((__bridge const void *)(self.aLayer)));//32
NSLog(@"------");
//针对于UILabel 和 CATextLayer内存对比
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(30, 300, 300, 44)];
label.text = @"label";
[self.view addSubview:label];
CATextLayer *textLayer = [[CATextLayer alloc] init];
textLayer.frame = CGRectMake(30, 400, 300, 44);
textLayer.string = @"CATextLayer";
[self.view.layer addSublayer:textLayer];
//比较UILabel对象个CATextLayer对象在内存中的大小
NSLog(@"label对象实际需要的内存大小: %zd", class_getInstanceSize([label class]));//744
NSLog(@"label对象实际分配的内存大小: %zd", malloc_size((__bridge const void *)(label)));//752
NSLog(@"textLayer对象实际需要的内存大小: %zd", class_getInstanceSize([textLayer class]));//32
NSLog(@"textLayer对象实际分配的内存大小: %zd", malloc_size((__bridge const void *)(textLayer)));//32
NSLog(@"------");
//添加了一些设置, 比如字体大小, 颜色, 换行, 字体长度变化
label.text = @"123456789012345678901234567890";
label.font = [UIFont fontWithName:@"PingFangSC-Regular" size:12];
label.textColor = [UIColor redColor];
textLayer.string = @"123456789012345678901234567890";
textLayer.font = (__bridge CFTypeRef _Nullable)(@"PingFangSC-Regular");
textLayer.fontSize = 12;
textLayer.foregroundColor = [UIColor redColor].CGColor;
//比较UILabel对象个CATextLayer对象在内存中的大小
NSLog(@"label对象实际需要的内存大小: %zd", class_getInstanceSize([label class]));//744
NSLog(@"label对象实际分配的内存大小: %zd", malloc_size((__bridge const void *)(label)));//752
NSLog(@"textLayer对象实际需要的内存大小: %zd", class_getInstanceSize([textLayer class]));//32
NSLog(@"textLayer对象实际分配的内存大小: %zd", malloc_size((__bridge const void *)(textLayer)));//32
}
打印结果
2019-09-12 11:06:33.017943+0800 Demo[7030:27412457] self.aView对象实际需要的内存大小: 480
2019-09-12 11:06:33.018123+0800 Demo[7030:27412457] self.aView对象实际分配的内存大小: 480
2019-09-12 11:06:33.018249+0800 Demo[7030:27412457] self.aLayer对象实际需要的内存大小: 24
2019-09-12 11:06:33.018367+0800 Demo[7030:27412457] self.aLayer对象实际分配的内存大小: 32
2019-09-12 11:06:33.018478+0800 Demo[7030:27412457] ------
2019-09-12 11:06:33.019261+0800 Demo[7030:27412457] label对象实际需要的内存大小: 744
2019-09-12 11:06:33.019357+0800 Demo[7030:27412457] label对象实际分配的内存大小: 752
2019-09-12 11:06:33.019443+0800 Demo[7030:27412457] textLayer对象实际需要的内存大小: 32
2019-09-12 11:06:33.019542+0800 Demo[7030:27412457] textLayer对象实际分配的内存大小: 32
2019-09-12 11:06:33.019651+0800 Demo[7030:27412457] ------
2019-09-12 11:06:33.023849+0800 Demo[7030:27412457] label对象实际需要的内存大小: 744
2019-09-12 11:06:33.024001+0800 Demo[7030:27412457] label对象实际分配的内存大小: 752
2019-09-12 11:06:33.024106+0800 Demo[7030:27412457] textLayer对象实际需要的内存大小: 32
2019-09-12 11:06:33.085927+0800 Demo[7030:27412457] textLayer对象实际分配的内存大小: 32
- 由此看得出来, 在对象的内存分配中, CATextLayer的内存大小明显要比UIView要轻量的多.
- 对于一些只是用来展示的控件,比如是UIlabel,或者是ImageView. 完全可以用Layer来代替.
- 简单粗暴来理解:所有集成于UIView的控件,它们自身带有一个CALayer层, 所以UIView里面的东西会比CALayer中的要多.
参考
UIView和CALayer之间的关系
UIView与CALayer的区别,很详细
网友评论