CALayer及其子类

CALayer

1.CALayer简介

CALayer包含在QuartzCore框架中,这是一个跨平台的框架,既可以用在iOS中又可以用在Mac OS X中。在iOS中,我们所看到的视图UIView是通过QuartzCore中的CALayer显示出来的,我们讨论的动画效果也是加在这个CALayer上的。

2.CALayer属性

CALayer主要是展示内容和动画操作,CALayer不包含在UIKit中,不能响应事件,由于CALayer在设计之初就考虑它的动画操作功能,CALayer很多属性在修改时都能形成动画效果,这种属性称为“隐式动画属性”,但是UIView的根Layer是没有隐式动画的。另外,UIView的根图层创建工作完全由iOS负责完成,无法重新创建,但是可以往根图层中添加子图层或移除子图层。

下表列出了CALayer常用的属性:
CALayer属性

3.CALayer的简单使用

3.1 设置UIView根layer

//初始化UIimageView对象
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"annotation"]];
//设置阴影
imageView.layer.shadowColor = [UIColor grayColor].CGColor;//颜色
imageView.layer.shadowOffset = CGSizeMake(10, 10);//偏移量
imageView.layer.shadowOpacity = 0.8;//不透明度
//设置圆角大小
imageView.layer.cornerRadius = 10;
//设置边框
imageView.layer.borderWidth = 2;//边框宽度
imageView.layer.borderColor = [UIColor redColor].CGColor;//边框颜色

3.2 添加一个显示显示图片的layer

//初始化layer对象
CALayer *imageLayer = [CALayer layer];
//设置图层的宽高
imageLayer.bounds = CGRectMake(0, 0, 100, 100);
//设置图层的位置
imageLayer.position = CGPointMake(200, Height_NavBar+70);
//设置需要显示的图片
imageLayer.contents = (id)[UIImage imageNamed:@"annotation"].CGImage;
// 设置层的圆角半径为10
imageLayer.cornerRadius = 10;
// 如果设置了图片,需要设置这个属性为YES才有圆角效果
imageLayer.masksToBounds = YES;
//设置旋转
imageLayer.transform = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);
//添加图层到控制器的view的layer上
[self.view.layer addSublayer:imageLayer];

4.CALayer绘图

在使用Quartz 2D绘图时,当调用了UIView的drawRect:方法绘制图形、图像,这种方式本质还是在图层中绘制,下面介绍如何直接在图层中绘图。
图层绘图有两种方法,不管使用哪种方法都要调用setNeedsDisplay(UIView和CALayer都有setNeedsDisplay方法, 而这里调用的是图层的方法)

4.1 使用代理方法绘图

首先设置图层代理,实现代理协议方法- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx,设置完代理后必须要调用图层的setNeedDisplay方法,否则绘制的内容无法显示。

- (void)setupLayerWitdDelegate{
    //初始化layer对象
    layer = [CALayer layer];
    //设置图层的宽高
    layer.bounds = CGRectMake(0, 0, 100, 100);
    //设置图层的位置
    layer.position = CGPointMake(70, Height_NavBar+200);
    //设置图层代理
    layer.delegate = self;
    //添加图层到控制器的view的layer上
    [self.view.layer addSublayer:layer];
    //调用图层setNeedDisplay,否则代理方法不会被调用
    [layer setNeedsDisplay];
}

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
    CGContextSaveGState(ctx);
    
    //图形上下文形变,解决图片倒立的问题
    CGContextScaleCTM(ctx, 1, -1);
    CGContextTranslateCTM(ctx, 0, -100);
    
    UIImage *image = [UIImage imageNamed:@"annotation"];
    
    //注意这个位置是相对于图层而言的不是屏幕
    CGContextDrawImage(ctx, CGRectMake(0, 0, 100, 100), image.CGImage);
    
    CGContextRestoreGState(ctx);

}

4.2 使用自定义图层绘图

在自定义图层中绘图时只要自己编写一个类继承于CALayer然后在drawInContext:中绘图即可。同前面在代理方法绘图一样,要显示图层中绘制的内容也要调用图层的setNeedDisplay方法,否则drawInContext方法将不会调用。

- (void)drawInContext:(CGContextRef)ctx{
    CGContextSaveGState(ctx);
    
    //图形上下文形变,解决图片倒立的问题
    CGContextScaleCTM(ctx, 1, -1);
    CGContextTranslateCTM(ctx, 0, -100);
    
    UIImage *image = [UIImage imageNamed:@"annotation"];
    
    //注意这个位置是相对于图层而言的不是屏幕
    CGContextDrawImage(ctx, CGRectMake(0, 0, 100, 100), image.CGImage);
    
    CGContextRestoreGState(ctx);   
}

CALayer的子类

CALayer子类

CALayer的子类有很多,下面说几个比较常用的:

CAShapeLayer

1.CAShapeLayer继承自CALayer,可使用CALayer的所有属性
2.CAShapeLayer是在坐标系内绘制贝塞尔曲线的,通过绘制贝塞尔曲线,设置shape(形状)的path(路径),从而绘制各种各样的图形以及不规则图形。因此,使用CAShapeLayer需要与UIBezierPath一起使用。
3.UIBezierPath类允许你在自定义的 View 中绘制和渲染由直线和曲线组成的路径.。你可以在初始化的时候直接为你的UIBezierPath指定一个几何图形。

- (void)setupShapeLayer{
    //创建路径
    UIBezierPath *path = [[UIBezierPath alloc]init];
    [path moveToPoint:CGPointMake(50, 320)];
    [path addQuadCurveToPoint:CGPointMake(300, 320) controlPoint:CGPointMake(100, 400)];
    [path addQuadCurveToPoint:CGPointMake(50, 320) controlPoint:CGPointMake(100, 350)];
    // 创建 shapeLayer
    CAShapeLayer *shapeLayer = [[CAShapeLayer alloc]init];
    [self.view.layer addSublayer:shapeLayer];
    //呈现的形状的路径
    shapeLayer.path = path.CGPath;
    //填充路径的颜色,默认颜色为不透明的黑色。
    shapeLayer.fillColor = [UIColor redColor].CGColor;
    //设置描边色,默认无色。
    shapeLayer.strokeColor = [UIColor greenColor].CGColor;
    //线的宽度,默认为1
    shapeLayer.lineWidth = 2;
    //lineJoin为线连接类型,其值也有三个类型,分别为kCALineJoinMiter、kCALineJoinRound、kCALineJoinBevel,默认值是Miter
    shapeLayer.lineJoin = kCALineJoinRound;
    //lineCap为线端点类型,值有三个类型,分别为kCALineCapButt 、kCALineCapRound 、kCALineCapSquare,默认值为Butt
    shapeLayer.lineCap = kCALineCapRound;
    
}

CAGradientLayer

CAGradientLayer继承自CALayer,它主要功能是能实现渐变的颜色
startPoint和endPoint表示颜色的渐变方向,locations是渐变区域。

- (void)setupGradintLayer{
    //创建gradientLayer
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.bounds = CGRectMake(0, 0, 100, 100);
    gradientLayer.position = CGPointMake(70, Height_NavBar+370);
    [self.view.layer addSublayer:gradientLayer];
    //渐变颜色的数组
    gradientLayer.colors = @[(__bridge id)[UIColor redColor].CGColor,
                             (__bridge id)[UIColor blueColor].CGColor];
    //渐变颜色的区间分布,默认是nil,会平均分布。
    gradientLayer.locations =  @[@(0.2), @(0.5), @(0.8)];
    // 起始点
    gradientLayer.startPoint = CGPointMake(0.0, 0.0);
    // 结束点
    gradientLayer.endPoint = CGPointMake(1.0, 1.0);
}

CAEmitterLayer

CAEmitterLayer 是一个高性能的粒子引擎,被用来创建复杂的粒子动画如:烟雾,火,雨等效果,并且很好地控制了性能。
iOS中的粒子效果有两部分组成,一部分为发射器CAEmitterLayer,另一部分是粒子单元CAEmitterCell,用于设置相应的粒子属性。

  • CAEmitterLayer的属性
 发射源位置。注意,是一个空间坐标。并且标记为 Animatable. 也就是说可以用 CoreAnimation 移动发射源位置

@property CGPoint emitterPosition;
@property CGFloat emitterZPosition; 
发射源大小。注意除了宽和高之外,还有纵向深度。
文档中还提到,这两个属性有时候可能会因为设置了 emitterShape 而被忽略,具体情况实际尝试一下就可以了。
@property CGSize emitterSize;
@property CGFloat emitterDepth;

CA_EXTERN NSString * const kCAEmitterLayerPoint
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerLine
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerRectangle
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerCuboid
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerCircle
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerSphere
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);

 emitterShape 决定了发射源的形状。
@property(copy) NSString *emitterShape;
   
CA_EXTERN NSString * const kCAEmitterLayerPoints
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerOutline
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerSurface
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);
CA_EXTERN NSString * const kCAEmitterLayerVolume
    __OSX_AVAILABLE_STARTING (__MAC_10_6, __IPHONE_5_0);

 emitterMode 决定了发射源的发射模式。
@property(copy) NSString *emitterMode;

  • CAEmitterCell的属性
@property float birthRate; //每秒生成多少个粒子
 
@property float lifetime; //粒子存活的时间,以秒为单位
@property float lifetimeRange; // 可以为这个粒子存活的时间再指定一个范围。
上面两个属性如果只用了lifetime那么粒子的存活时间就是固定的,比如lifetime=10,那么粒子10s秒后就消失了。
如果使用了lifetimeRange,比如lifetimeRange=5,那么粒子的存活时间就是在5s~15s这个范围内消失。
 
@property CGFloat velocity;//粒子平均初始速度。正数表示竖直向上,负数竖直向下。
@property CGFloat velocityRange; //可以再指定一个范围。
上面两个属性同lifetime和lifetimeRange
 
@property CGFloat xAcceleration;
@property CGFloat yAcceleration;
@property CGFloat zAcceleration; //三者构成了一个空间矢量。决定了每个方向上粒子的加速度。
 
@property CGFloat emissionRange; //以锥形分布开的发射角度。角度用弧度制。粒子均匀分布在这个锥形范围内。
 
@property CGFloat spin;//粒子的平均旋转速度
@property CGFloat spinRange; //可指定一个范围。弧度制。
 
@property(strong) id contents; //cell的内容。通常是一个指针CGImageRef。
 
@property CGColorRef color; //可以把图片「染」成你想要的颜色。

@property(copy) NSString *name; //The name of the cell,用于构建key paths。这也是后面手动控制动画开始和结束的关键。

CAReplicatorLayer

CAReplicatorLayer是一个高效处理复制图层的中间层。他能复制图层的所有属性,包括动画。

  • CAReplicatorLayer的属性
//指定图层重复制多少次
@property NSInteger instanceCount;

//设置为YES,图层将保持于CATransformLayer类似的性质和相同的限制
@property BOOL preservesDepth;

//复制延时,一般用在动画上
@property CFTimeInterval instanceDelay;

//3D变换
@property CATransform3D instanceTransform;

//设置多个复制图层的颜色,默认位白色
@property(nullable) CGColorRef instanceColor;

//设置每个复制图层相对上一个复制图层的红色、绿色、蓝色、透明度偏移量
@property float instanceRedOffset;
@property float instanceGreenOffset;
@property float instanceBlueOffset;
@property float instanceAlphaOffset;

CATextLayer

Core Animation提供了一个CALayer的子类CATextLayer,它以图层的形式包含了UILabel几乎所有的绘制特性,并且额外提供了一些新的特性。

  • CATextLayer的属性
//渲染的文字字符串
@property(nullable, copy) id string;
//设置字体
@property(nullable) CFTypeRef font;
//设置字号
@property CGFloat fontSize;
//设置文字颜色
@property(nullable) CGColorRef foregroundColor;
//是否换行
@property(getter=isWrapped) BOOL wrapped;
/*
设置截断模式
NSString * const kCATruncationNone;
截断前部分
NSString * const kCATruncationStart;
截断后部分
NSString * const kCATruncationEnd;
截断中间
NSString * const kCATruncationMiddle;
*/
@property(copy) NSString *truncationMode;
/*
设置文字对齐模式
NSString * const kCAAlignmentNatural;
NSString * const kCAAlignmentLeft;
NSString * const kCAAlignmentRight;
NSString * const kCAAlignmentCenter;
NSString * const kCAAlignmentJustified;
*/
@property(copy) NSString *alignmentMode;

参考:完整项目资料下载

你可能感兴趣的:(CALayer及其子类)