CAShapeLayer & CALayer
- CAShapeLayer继承自CALayer,因此,可使用CALayer的所有属性。CAShapeLayer有不同于CALayer的属性,它从CALayer继承而来的属性在绘制时是不起作用的。
- 普通CALayer在被初始化的时候是需要给一个frame的值的,这个frame值一般都与给定view的bounds值一致,它本身是有形状的,而且是矩形。CAShapeLayer初始化时也需要指定frame值,但它本身没有形状,它的形状来源于其属性path。
- CAShapeLayer高效使用内存。一个CAShapeLayer不需要像普通CALayer一样创建一个寄宿图形,所以无论有多大,都不会占用太多的内存。
- CAShapeLayer不会被图层边界剪裁掉。一个CAShapeLayer可以在边界之外绘制。图层路径不会像在使用Core Graphics的普通CALayer一样被剪裁掉。
CAShapeLayer & UIBezierPath
- CAShapeLayer是基于贝塞尔曲线而存在的。CAShapeLayer依附于一个给定的path(路径),必须给与path,path由贝塞尔曲线提供,CAShapeLayer在提供的路径中进行渲染。路径会闭环,所以绘制出了形状。
CAShapeLayer & DrawRect
- CAShapeLayer属于CoreAnimation框架,通过GPU来渲染图形,节省性能。动画渲染直接提交给手机GPU,不消耗内存。
- DrawRect:DrawRect属于CoreGraphic框架,占用CPU,消耗性能大。
- 使用CAShapeLayer与贝塞尔曲线可以实现不在view的DrawRect方法中画出一些想要的图形
1、[CAShapeLayer layer].path
-(void)initUI{
UIBezierPath * path = [UIBezierPath bezierPath];
[path addArcWithCenter:CGPointMake(200.0, 300.0) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
CAShapeLayer *shaperLayer = [CAShapeLayer layer];
shaperLayer.path =path.CGPath;
shaperLayer.strokeColor =[UIColor blueColor].CGColor;
shaperLayer.fillColor = [UIColor whiteColor].CGColor;
shaperLayer.lineWidth = 2;
shaperLayer.frame = self.view.bounds;
[self.view.layer addSublayer:shaperLayer];
[self drawLineAnimation:shaperLayer];
}
- (void)drawLineAnimation:(CALayer*)layer{
CABasicAnimation * bas =[CABasicAnimation animationWithKeyPath:@"strokeEnd"];
bas.duration = 3;
bas.fromValue =[NSNumber numberWithInteger:0];
bas.toValue =[NSNumber numberWithInteger:1];
[layer addAnimation:bas forKey:@"key"];
}
2、[CAShapeLayer layer].fillColor
-(void)initUI{
UIBezierPath * path = [UIBezierPath bezierPath];
[path addArcWithCenter:CGPointMake(200.0, 300.0) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
CAShapeLayer *shaperLayer = [CAShapeLayer layer];
shaperLayer.path =path.CGPath;
shaperLayer.strokeColor =[UIColor blueColor].CGColor;
shaperLayer.fillColor = [UIColor redColor].CGColor;
shaperLayer.lineWidth = 2;
shaperLayer.frame = self.view.bounds;
[self.view.layer addSublayer:shaperLayer];
[self drawLineAnimation:shaperLayer];
}
- (void)drawLineAnimation:(CALayer*)layer{
CABasicAnimation * bas =[CABasicAnimation animationWithKeyPath:@"fillColor"];
bas.duration = 3;
bas.fromValue =(__bridge id)[UIColor redColor].CGColor;
bas.toValue =(__bridge id)[UIColor blueColor].CGColor;
[layer addAnimation:bas forKey:@"key"];
}
3、[CAShapeLayer layer].fillRule
解释:官方解释是当在填充颜色的时候则就需要这种填充规则,值有两种,非零和奇偶数,但默认是非零值。
属性用于指定使用哪一种算法去判断画布上的某区域是否属于该图形“内部” (内部区域将被填充)。对一个简单的无交叉的路径,哪块区域是“内部” 是很直观清除的。但是,对一个复杂的路径,比如自相交或者一个子路径包围另一个子路径,“内部”的理解就不那么明确了。
kCAFillRuleNonZero
字面意思是“非零”。按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点情况。从0开始计数,路径从左向右穿过射线则计数加1,从右向左穿过射线则计数减1。得出计数结果后,如果结果是0,则认为点在图形外部,否则认为在内部。
kCAFillRuleEvenOdd
字面意思是“奇偶”。按该规则,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点的数量。如果结果是奇数则认为点在内部,是偶数则认为点在外部。
4、[CAShapeLayer layer].strokeColor
这个属性用于设置描边的颜色,如果不需要描边就传nil,默认就是nil,该属性还是可动画的。
5、[CAShapeLayer layer].strokeStart 与 [CAShapeLayer layer].strokeEnd
解释:这些值定义了用于绘制描边轮廓的路径的子区域。 值必须在[0,1]的范围内,其中0表示路径的开始,1表示结束。 介于0和1之间的值沿路径长度线性插值。strokeStart默认为零,strokeEnd默认为1。 两者都是可以动画的。
-(void)initUI{
UIBezierPath * path = [UIBezierPath bezierPath];
[path addArcWithCenter:CGPointMake(200.0, 300.0) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
CAShapeLayer *shaperLayer = [CAShapeLayer layer];
shaperLayer.path = path.CGPath;
shaperLayer.strokeColor = [UIColor blueColor].CGColor;
shaperLayer.fillColor = [UIColor redColor].CGColor;
shaperLayer.fillRule = kCAFillRuleEvenOdd;
shaperLayer.lineWidth = 2;
shaperLayer.strokeStart = 0.1;
shaperLayer.frame = self.view.bounds;
[self.view.layer addSublayer:shaperLayer];
[self drawLineAnimation:shaperLayer];
}
- (void)drawLineAnimation:(CALayer*)layer{
CABasicAnimation * bas =[CABasicAnimation animationWithKeyPath:@"strokeEnd"];
bas.duration = 3;
bas.fromValue =@0.1;
bas.toValue =@0.9;
[layer addAnimation:bas forKey:@"key"];
}
6、[CAShapeLayer layer].lineWidth 和 [CAShapeLayer layer].miterLimit
官方解释是lineWidth为线的宽度,默认为1;miterLimit为最大斜接长度。斜接长度指的是在两条线交汇处和外交之间的距离。只有lineJoin属性为kCALineJoinMiter时miterLimit才有效。边角的角度越小,斜接长度就会越大。为了避免斜接长度过长,我们可以使用miterLimit属性。如果斜接长度超过miterLimit的值,边角会以lineJoin的“bevel”即kCALineJoinBevel类型来显示。
7、[CAShapeLayer layer].lineCap 与 [CAShapeLayer layer].lineJoin
lineCap为线端点类型,值有三个类型,分别为kCALineCapButt 、kCALineCapRound 、kCALineCapSquare,默认值为Butt;
lineJoin为线连接类型,其值也有三个类型,分别为kCALineJoinMiter、kCALineJoinRound、kCALineJoinBevel,默认值是Miter。
8、[CAShapeLayer layer].lineDashPhase 与 [CAShapeLayer layer].lineDashPattern
官方解释是lineDashPhase为线型模版的起始位置;lineDashPattern为线性模版,这是一个NSNumber的数组,索引从1开始记,奇数位数值表示实线长度,偶数位数值表示空白长度。
lineDashPhase:
设置边线的样式,默认为实线,该数组为一个NSNumber数组,数组中的数值依次表示虚线中单个线的长度
,和空白的长度
,如:数组@[2,2,3,4] 表示 有长度为2的线,长度为2的空白,长度为3的线,长度为4的空白,不断循环后组成的虚线。ineDashPattern:
边线样式的起始位置,即,如果lineDashPattern
设置为@[@2, @2, @3, @4],lineDashPhase即为第一个长度为2的线的起始位置,默认值为0,可动画
注:fillColor与strokeColor都是在有UIBezierPath参数配置的情况下才能发生作用
-(void)initUI{
UIBezierPath * path = [UIBezierPath bezierPath];
[path addArcWithCenter:CGPointMake(200.0, 300.0) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
CAShapeLayer *shaperLayer = [CAShapeLayer layer];
shaperLayer.path = path.CGPath;
shaperLayer.strokeColor = [UIColor blueColor].CGColor;
shaperLayer.fillColor = [UIColor redColor].CGColor;
shaperLayer.fillRule = kCAFillRuleEvenOdd;
shaperLayer.lineWidth = 2;
shaperLayer.strokeStart = 0.1;
shaperLayer.frame = self.view.bounds;
[self.view.layer addSublayer:shaperLayer];
shaperLayer.lineDashPattern = @[@2, @3, @4, @5];
shaperLayer.lineDashPhase = 1;
[self drawLineAnimation:shaperLayer];
}
- (void)drawLineAnimation:(CALayer*)layer{
CABasicAnimation * bas =[CABasicAnimation animationWithKeyPath:@"strokeEnd"];
bas.duration = 3;
bas.fromValue =@0.1;
bas.toValue =@0.9;
[layer addAnimation:bas forKey:@"key"];
}