神奇的CALayer
2018-11-18 本文已影响0人
木木一直在哭泣
一、CALayer
CALayer类在概念上和UIView类似,也可以像View一样添加一些子layer(图片,文本等等),也能够像View一样,管理子图层的位置大小等等,并且CALayer有一些非常重要的属性和方法,iOS中的动画就是通过这些来做动画和变换,CALayer和UIView最大的不同就是CALayer不处理用户的交互。
二、UIView和CALayer之间的区别
1、UIView是用来显示内容的,可以处理用户事件。直接继承UIResponser。
2、CALayer是用来绘制内容的,不能处理用户事件。直接继承NSObject。
3、 UIView和CALayer是相互依赖的关系。UIView依赖于CALayer提供的内容,CALayer依赖UIView提供的容器来显示绘制的内容。
三、CALayer的常用属性
//宽度和高度
@property CGRect bounds;
//位置(默认指中点,具体由anchorPoint决定)
@property CGPoint position;
//锚点(x,y的范围都是0-1),决定了position的含义
@property CGPoint anchorPoint;
//背景颜色(CGColorRef类型)
@propertyCGColorRefbackgroundColor;
//形变属性
@property CATransform3D transform;
//边框颜色(CGColorRef类型)
@property CGColorRef borderColor;
//边框宽度
@property CGFloat borderWidth;
//圆角半径
@property CGFloat cornerRadius;
//内容(比如设置为图片CGImageRef)
@property(retain) id contents;
可以通过设置contents属性给UIView设置背景图片:
UIImage *image = [UIImage imageNamed:@"Snowman.png"];
self.layerView.layer.contents = (__bridge id)image.CGImage;
给contents赋CGImage的值不是唯一的设置寄宿图的方法。我们可以直接用Core Graphics直接绘制寄宿图。能够通过继承UIView并实现-drawRect: 方法来自定义绘制。如果你不需要寄宿图,那就不要创建这个方法了,这会造成CPU资源和内存的浪费,这也是为什么苹果建议:如果没有自定义绘制的任务就不要在子类中写一个空的-drawRect:方法。
四、专用图层
- CAShapeLayer
CAShapeLayer是一个通过矢量图形而不是bitmap来绘制的图层子类。你指定诸如颜色和线宽等属性,用CGPath来定义想要绘制的图形,最后CAShapeLayer就自动渲染出来了。当然,你也可以用Core Graphics直接向原始的CALyer的内容中绘制一个路径,相比直下,使用CAShapeLayer有以下一些优点:- 渲染快速。CAShapeLayer使用了硬件加速,绘制同一图形会比用Core Graphics快很多。
- 高效使用内存。一个CAShapeLayer不需要像普通CALayer一样创建一个寄宿图形,所以无论
有多大,都不会占用太多的内存。 - 不会被图层边界剪裁掉。一个CAShapeLayer可以在边界之外绘制。你的图层路径不会像在使
- 用Core Graphics的普通CALayer一样被剪裁掉(如我们在第二章所见)。
不会出现像素化。当你给CAShapeLayer做3D变换时,它不像一个有寄宿图的普通图层一样变得像素化。
- CAGradientLayer
CAGradientLayer是用来生成两种或更多颜色平滑渐变的。用Core Graphics复制一个CAGradientLayer并将内容绘制到一个普通图层的寄宿图也是有可能的,但是CAGradientLayer的真正好处在于绘制使用了硬件加速。
CAGradientLayer和CAShapeLayer可以一起使用,进行复杂图形的绘制。
例如:
self.view.backgroundColor = [UIColor colorWithRed:102.0/255.0 green:184.0/255.0 blue:234.0/255.0 alpha:1.0];
UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(80, 100, 100, 100)];
UIBezierPath *roundPath = [UIBezierPath bezierPathWithRect:CGRectMake(110, 150, 100, 100)];
[circlePath appendPath:roundPath];
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(150, 200, 100, 100) byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(30, 30)];
[circlePath appendPath:path];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = circlePath.CGPath;
shapeLayer.fillColor = self.view.backgroundColor.CGColor;
CAGradientLayer * gradientLayer = [[CAGradientLayer alloc] init];
gradientLayer.frame = self.view.bounds;
gradientLayer.startPoint = CGPointMake(0, 0);
gradientLayer.endPoint = CGPointMake(0, 1);
gradientLayer.colors = @[(__bridge id)[UIColor colorWithWhite:0 alpha:0.4].CGColor,
(__bridge id)[UIColor colorWithWhite:0 alpha:0.82].CGColor];
gradientLayer.mask = shapeLayer;
[self.view.layer addSublayer:gradientLayer];
运行效果:
CA39CF825B4E8FF56062B8694CFE288E.png
- CAEmitterLayer
在iOS 5中,苹果引入了一个新的CALayer子类叫做CAEmitterLayer。CAEmitterLayer是一个高性能的粒子引擎,被用来创建实时例子动画如:烟雾,火,雨等等这些效果。
CAEmitterLayer看上去像是许多CAEmitterCell的容器,这些CAEmitierCell定义了一个例子效果。你将会为不同的例子效果定义一个或多个CAEmitterCell作为模版,同时CAEmitterLayer负责基于这些模版实例化一个粒子流。一个CAEmitterCell类似于一个CALayer:它有一个contents属性可以定义为一个CGImage,另外还有一些可设置属性控制着表现和行为。我们不会对这些属性逐一进行详细的描述,你们可以在CAEmitterCell类的头文件中找到。