zoukankan      html  css  js  c++  java
  • CAShapeLayer

    之前讲过CALayer动画相关知识,再来看看更加复杂的CAShapeLayer相关的动画知识.

    普通CALayer在被初始化时是需要给一个frame值的,这个frame值一般都与给定view的bounds值一致,它本身是有形状的,而且是矩形.

    CAShapeLayer在初始化时也需要给一个frame值,但是,它本身没有形状,它的形状来源于你给定的一个path,然后它去取CGPath值,它与CALayer有着很大的区别

    CAShapeLayer有着几点很重要:

    1. 它依附于一个给定的path,必须给与path,而且,即使path不完整也会自动首尾相接

    2. strokeStart以及strokeEnd代表着在这个path中所占用的百分比

    3. CAShapeLayer动画仅仅限于沿着边缘的动画效果,它实现不了填充效果

    以下给出如何使用CAShapeLayer

        // 创建一个view
        UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
        [self.view addSubview:showView];
        showView.backgroundColor = [UIColor redColor];
        showView.alpha = 0.5;

        // 贝塞尔曲线(创建一个圆)
        UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100 / 2.f, 100 / 2.f)
                                                            radius:100 / 2.f
                                                        startAngle:0
                                                          endAngle:M_PI * 2
                                                         clockwise:YES];

        // 创建一个shapeLayer
        CAShapeLayer *layer = [CAShapeLayer layer];
        layer.frame         = showView.bounds;                // 与showView的frame一致
        layer.strokeColor   = [UIColor greenColor].CGColor;   // 边缘线的颜色
        layer.fillColor     = [UIColor clearColor].CGColor;   // 闭环填充的颜色
        layer.lineCap       = kCALineCapSquare;               // 边缘线的类型
        layer.path          = path.CGPath;                    // 从贝塞尔曲线获取到形状
        layer.lineWidth     = 4.0f;                           // 线条宽度
        layer.strokeStart   = 0.0f;
        layer.strokeEnd     = 0.1f;

        // 将layer添加进图层
        [showView.layer addSublayer:layer];

        // 3s后执行动画操作(直接赋值就能产生动画效果)
        [[GCDQueue mainQueue] execute:^{
            layer.speed       = 0.1;
            layer.strokeStart = 0.5;
            layer.strokeEnd   = 0.9f;
            layer.lineWidth   = 1.0f;
        } afterDelay:NSEC_PER_SEC * 3];

        // 给这个layer添加动画效果
        CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
        pathAnimation.duration = 1.0;
        pathAnimation.fromValue = [NSNumber numberWithFloat:0.5f];
        pathAnimation.toValue = [NSNumber numberWithFloat:0.8f];
        [layer addAnimation:pathAnimation forKey:nil]; 

        // 创建一个gradientLayer
        CAGradientLayer *gradientLayer =  [CAGradientLayer layer];
        gradientLayer.frame = showView.bounds;
        [gradientLayer setColors:[NSArray arrayWithObjects:
                                   (id)[[UIColor redColor] CGColor],
                                   (id)[[UIColor yellowColor] CGColor], nil]];
        [gradientLayer setLocations:@[@0.5,@0.9,@1]];
        [gradientLayer setStartPoint:CGPointMake(0.5, 1)];
        [gradientLayer setEndPoint:CGPointMake(0.5, 0)];

    附录:

    TestView.h

    复制代码
    #import <UIKit/UIKit.h>
    
    @interface TestView : UIView
    
    {
        
        CAShapeLayer *layer;
        
    }
    
    - (void)strokeStart:(CGFloat)value;
    - (void)strokeEnd:(CGFloat)value;
    
    @end
    复制代码

    TestView.m

    复制代码
    #import "TestView.h"
    
    @implementation TestView
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self)
        {
            layer = [CAShapeLayer layer];
            layer.frame = self.bounds;
            
            UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.height / 2.0f,
                                                                                   self.frame.size.height / 2.0f)
                                                                radius:self.frame.size.height / 2.f
                                                            startAngle:0
                                                              endAngle:M_PI * 2
                                                             clockwise:YES];
            
            layer.strokeColor   = [UIColor greenColor].CGColor;   // 边缘线的颜色
            layer.fillColor     = [UIColor clearColor].CGColor;   // 闭环填充的颜色
            layer.lineCap       = kCALineCapSquare;               // 边缘线的类型
            layer.path          = path.CGPath;                    // 从贝塞尔曲线获取到形状
            layer.lineWidth     = 1.0f;                           // 线条宽度
            layer.strokeStart   = 0.0f;
            layer.strokeEnd     = 0.0f;
            
            [self.layer addSublayer:layer];
        }
        return self;
    }
    
    - (void)strokeStart:(CGFloat)value
    {
        layer.speed = 1;
        layer.strokeStart = value;
    }
    
    - (void)strokeEnd:(CGFloat)value
    {
        layer.speed = 1;
        layer.strokeEnd = value;
    }
    
    @end
    相关资料:
    http://blog.csdn.net/volcan1987/article/details/9969455
    http://www.cocoachina.com/ios/20160214/15251.html
    http://www.cocoachina.com/industry/20140705/9039.html
  • 相关阅读:
    【CentOS_7】使用tcpdump抓明文包
    【MySQL】MySQL-front等客户端连接MySQL_8.0等失败的解决办法
    【Python3.6】python打包成exe
    【BIGDATA】将普通文本文件导入ElasticSearch
    【python 3.6】类:访问属性及调用方法
    错误:The method replace(int, Fragment) in the type FragmentTransaction is not applicable for the arguments (int, MyFragment)
    Android Your content must have a ListView whose id attribute is 'android.R.id.list'错误的解决办法
    将文件放到Android模拟器的SD卡
    eclipse连接虚拟机
    Android 模拟器genymotion安装,eclipse 插件
  • 原文地址:https://www.cnblogs.com/wcLT/p/5190804.html
Copyright © 2011-2022 走看看