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