美文网首页ios动画
CALayer及其子类

CALayer及其子类

作者: 陌巷先森 | 来源:发表于2019-02-28 10:17 被阅读0次

    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及其子类

        本文链接:https://www.haomeiwen.com/subject/bbdlpftx.html