CAShapeLayer
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-YWan5iMxcTYlVmN3Q2MlJWZzYmY1M2NyI2NlZWY2QzNmZmYw8CX3AzLchDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL2M3Lc9CX6MHc0RHaiojIsJye.gif)
之前講過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