天天看點

CAShapeLayer(持續更新)

CAShapeLayer

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