iOS CAShapeLayer精讲

摘要:
前言CAShapeLayer继承自CALayer,因此可以使用CALayer的所有属性。然而,CAShapeLayer需要与Bezier曲线一起使用才能有意义。这里,CAShapeLayer在其坐标系中绘制Bezier曲线。动画渲染直接提交给移动GPU,不消耗内存。这两个都有自己的目的,并不是说有了CAShapeLayer,就不需要drawRect了。我们直接将CAShaperLayer放入自身。视图图层。我们创建一个CAShapeLayer,配置相关属性,通过UIBezierPath类方法创建内切圆路径,然后将路径分配给CAShapeLyer。连接两者的路径。
前言

CAShapeLayer继承自CALayer,因此,可使用CALayer的所有属性。但是,CAShapeLayer需要和贝塞尔曲线配合使用才有意义。

关于UIBezierPath,请阅读文章:iOS UIBezierPth精讲

基本知识

看看官方说明:

 
1
2
3
4
5
6
7
8
9
 
/* The shape layer draws a cubic Bezier spline in its coordinate space.
*
* The spline is described using a CGPath object and may have both fill
* and stroke components (in which case the stroke is composited over
* the fill). The shape as a whole is composited between the layer's
* contents and its first sublayer.
*/
 

上面只是部分说明内容,由于较长,只放一部分出来。这里是说CAShapeLayer是在其坐标系统内绘制贝塞尔曲线的。因此,使用CAShapeLayer需要与UIBezierPath一起使用。

它有一个path属性,而UIBezierPath就是对CGPathRef类型的封装,因此这两者配合起来使用才可以的哦!

 
1
2
3
 
@property(nullable)CGPathRefpath;
 
CAShapeLayer和drawRect的比较
  • drawRect:属于CoreGraphics框架,占用CPU,性能消耗大,不建议重写
  • CAShapeLayer:属于CoreAnimation框架,通过GPU来渲染图形,节省性能。动画渲染直接提交给手机GPU,不消耗内存

这两者各有各的用途,而不是说有了CAShapeLayer就不需要drawRect

温馨提示:drawRect只是一个方法而已,是UIView的方法,重写此方法可以完成我们的绘制图形功能。

CAShapeLayer与UIBezierPath的关系

CAShapeLayerUIBezierPath的关系:

  1. CAShapeLayershape代表形状的意思,所以需要形状才能生效
  2. 贝塞尔曲线可以创建基于矢量的路径,而UIBezierPath类是对CGPathRef的封装
  3. 贝塞尔曲线给CAShapeLayer提供路径,CAShapeLayer在提供的路径中进行渲染。路径会闭环,所以绘制出了Shape
  4. 用于CAShapeLayer的贝塞尔曲线作为path,其path是一个首尾相接的闭环的曲线,即使该贝塞尔曲线不是一个闭环的曲线
CAShapeLayer与UIBezierPath画圆

效果图如下:

image

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
-(CAShapeLayer*)drawCircle{
  CAShapeLayer*circleLayer=[CAShapeLayerlayer];
  // 指定frame,只是为了设置宽度和高度
  circleLayer.frame=CGRectMake(0,0,200,200);
  // 设置居中显示
  circleLayer.position=self.view.center;
  // 设置填充颜色
  circleLayer.fillColor=[UIColorclearColor].CGColor;
  // 设置线宽
  circleLayer.lineWidth=2.0;
  // 设置线的颜色
  circleLayer.strokeColor=[UIColorredColor].CGColor;
  
  // 使用UIBezierPath创建路径
  CGRectframe=CGRectMake(0,0,200,200);
  UIBezierPath*circlePath=[UIBezierPath bezierPathWithOvalInRect:frame];
  
  // 设置CAShapeLayer与UIBezierPath关联
  circleLayer.path=circlePath.CGPath;
  
  // 将CAShaperLayer放到某个层上显示
  [self.view.layer addSublayer:circleLayer];
  
  returncircleLayer;
}
 

注意,我们这里不是放在-drawRect:方法中调用的。我们直接将这个CAShaperLayer放到了self.view.layer上,直接呈现出来。

我们创建一个CAShapeLayer,然后配置相关属性,然后再通过UIBezierPath的类方法创建一个内切圆路径,然后将路径指定给CAShapeLayer.path,这就将两者关联起来了。最后,将这个层放到了self.view.layer上呈现出来。

CAShapeLayer与UIBezierPath的简单Loading效果

效果图类似这样(懒自己做图,就百度了一个):

image

我们调用了上面这个画圆效果的代码:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 
-(void)drawHalfCircle{
  self.loadingLayer=[selfdrawCircle];
  
  // 这个是用于指定画笔的开始与结束点
  self.loadingLayer.strokeStart=0.0;
  self.loadingLayer.strokeEnd=0.75;
  
  self.timer=[NSTimer scheduledTimerWithTimeInterval:0.1
                                                target:self
                                              selector:@selector(updateCircle)
                                              userInfo:nil
                                               repeats:YES];
}
 
-(void)updateCircle{
  if(self.loadingLayer.strokeEnd>1&&self.loadingLayer.strokeStart<1){
    self.loadingLayer.strokeStart+=0.1;
  }elseif(self.loadingLayer.strokeStart==0){
    self.loadingLayer.strokeEnd+=0.1;
  }
  
  if(self.loadingLayer.strokeEnd==0){
    self.loadingLayer.strokeStart=0;
  }
  
  if(self.loadingLayer.strokeStart>=1&&self.loadingLayer.strokeEnd>=1){
    self.loadingLayer.strokeStart=0;
    [self.timer invalidate];
    self.timer=nil;
  }
}
 

我们要实现这个效果,是通过strokeStarstrokeEnd这两个属性来完成的,看看官方说明:

 
1
2
3
4
5
6
7
8
9
10
11
 
/* These values define the subregion of the path used to draw the
* stroked outline. The values must be in the range [0,1] with zero
* representing the start of the path and one the end. Values in
* between zero and one are interpolated linearly along the path
* length. strokeStart defaults to zero and strokeEnd to one. Both are
* animatable. */
 
@propertyCGFloatstrokeStart;
@propertyCGFloatstrokeEnd;
 

这里说明了这两个值的范围是[0,1],当strokeStart的值为0慢慢变成1时,我们看到路径是慢慢消失的。这里实现的效果并不好,因为不能一起循环着。不过,在这里学习的目的已经达到了,后面学习动画效果时,才专门学习它。

免责声明:文章转载自《iOS CAShapeLayer精讲》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ceres---相机重投影误差JS 英文不截断单词截取下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

【原】iOS学习之Quartz2D(1)

什么是Quartz2D  1、Quartz 2D 是一个二维绘图引擎,同时支持iOS和Mac系统  2、Quartz 2D 能完成的工作: 绘制图形 : 线条三角形矩形圆弧等 绘制文字 绘制生成图片(图像) 读取生成PDF 截图裁剪图片 自定义UI控件 图形上下文  1、图形上下文(Graphics Context):是一个 CGContextRef...

ios画曲线

画曲线: - (void)drawRect:(CGRect)rect { UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(140, 40)]; //添加两个控制点 和 终点 [path addCurveToPoint:...

CALayer的子类之CAShapeLayer

一,CAShapeLayer介绍 * CAShapeLayer继承自CALayer,属于QuartzCore框架,可使用CALayer的所有属性。CAShapeLayer是在坐标系内绘制贝塞尔曲线的,通过绘制贝塞尔曲线,设置shape(形状)的path(路径),从而绘制各种各样的图形以及不规则图形。因此,使用CAShapeLayer需要与UIBezierP...

UIBezierPath精讲

前言 笔者在写本篇文章之前,也没有系统学习过贝塞尔曲线,只是曾经某一次的需求需要使用到,才临时百度看了一看而且使用最基本的功能。现在总算有时间停下来好好研究研究这个神奇而伟大的贝塞尔先生! 笔者在学习时,首先看了两遍UIBezierPath类头文件定义,熟悉了一下相关的属性和方法。 基础知识 使用UIBezierPath可以创建基于矢量的路径,此类是Cor...

ios中为视图添加圆角

1.使用 layer设置指定圆角 或者设定一个或几个圆角   码修 关注2017.04.20 19:03* 字数 107 阅读 656评论 0喜欢 0 由于项目中需要给按钮左下 和左上加圆角,我司可爱的ui君并不想给我切图。所以只有自己画了。由于很久没有用过这些知识,花了一些时间,故记入笔记。也可以用来画半圆。选择要画圆角的位置只需要改变枚举即可...

ios 动画系列之六------UIBezierPath贝塞尔弧线常用方法记

//根据一个矩形画曲线 + (UIBezierPath*)bezierPathWithRect:(CGRect)rect //根据矩形框的内切圆画曲线 + (UIBezierPath*)bezierPathWithOvalInRect:(CGRect)rect //根据矩形画带圆角的曲线 + (UIBezierPath*)bezierPathWith...