前言

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) CGPathRef path;
 

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画圆

效果图如下:

 
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 = [CAShapeLayer layer];
  // 指定frame,只是为了设置宽度和高度
  circleLayer.frame = CGRectMake(0, 0, 200, 200);
  // 设置居中显示
  circleLayer.position = self.view.center;
  // 设置填充颜色
  circleLayer.fillColor = [UIColor clearColor].CGColor;
  // 设置线宽
  circleLayer.lineWidth = 2.0;
  // 设置线的颜色
  circleLayer.strokeColor = [UIColor redColor].CGColor;
  
  // 使用UIBezierPath创建路径
  CGRect frame = CGRectMake(0, 0, 200, 200);
  UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:frame];
  
  // 设置CAShapeLayer与UIBezierPath关联
  circleLayer.path = circlePath.CGPath;
  
  // 将CAShaperLayer放到某个层上显示
  [self.view.layer addSublayer:circleLayer];
  
  return circleLayer;
}
 

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

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

CAShapeLayer与UIBezierPath的简单Loading效果

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

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

 
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 = [self drawCircle];
  
  // 这个是用于指定画笔的开始与结束点
  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;
  } else if (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. */
 
@property CGFloat strokeStart;
@property CGFloat strokeEnd;
 

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

CAShapeLayer和贝塞尔曲线配合使用的更多相关文章

  1. CAShapeLayer 与贝塞尔曲线

    一 CAShapeLayer 简介 1,CAShapeLayer继承至CALayer,可以使用CALayer的所有属性 2,CAShapeLayer需要与贝塞尔曲线配合使用才有意义:单独使用毫无意义 ...

  2. 基于CAShapeLayer和贝塞尔曲线的圆形进度条动画

    通过CAShapeLayer和贝塞尔曲线搭配的方法,创建的简单的圆形进度条的教程先简单的介绍下CAShapeLayer1,CAShapeLayer继承自CALayer,可使用CALayer的所有属性2 ...

  3. 基于CAShapeLayer和贝塞尔曲线的圆形进度条动画【装载】

    初次接触CAShapeLayer和贝塞尔曲线,看了下极客学院的视频.对初学者来说感觉还不错.今天来说一个通过CAShapeLayer和贝塞尔曲线搭配的方法,创建的简单的圆形进度条的教程先简单的介绍下C ...

  4. 贝塞尔曲线 & CAShapeLayer & Stroke 动画 浅谈

    转载自:http://46aae4d1e2371e4aa769798941cef698.devproxy.yunshipei.com/qiaoqiaoqiao2014/article/details/ ...

  5. [控件] 动态实时设置CAShapeLayer贝塞尔曲线的坐标点

    动态实时设置CAShapeLayer贝塞尔曲线的坐标点 效果图: 源码: PathDirectionView.h 与 PathDirectionView.m // // PathDirectionVi ...

  6. 贝塞尔曲线与CAShapeLayer的关系以及Stroke动画

    1.贝塞尔曲线与CAShapeLayer的关系    1.1CAShapeLayer须要一个形状才干生效,贝塞尔曲线能够创建基于矢量的路径.进而能够给CAShapeLayer提供路径,路径会闭环.   ...

  7. iOS贝塞尔曲线(UIBezierPath)的基本使用方法

    简介 UIBezierPath是对Core Graphics框架的一个封装,使用UIBezierPath类我们可以画出圆形(弧线)或者多边形(比如:矩形)等形状,所以在画复杂图形的时候会经常用到. 分 ...

  8. UIBezierPath IOS贝塞尔曲线

    //记录  贝塞尔曲线使用 //根据一个矩形画曲线 + (UIBezierPath *)bezierPathWithRect:(CGRect)rect //根据矩形框的内切圆画曲线 + (UIBezi ...

  9. 通过UIBezierPath贝塞尔曲线画圆形、椭圆、矩形

    /**创建椭圆形的贝塞尔曲线*/ UIBezierPath *_ovalPath=[UIBezierPath bezierPathWithOvalInRect:CGRectMake(, , , )]; ...

随机推荐

  1. Dividing coins (01背包)

    It’s commonly known that the Dutch have invented copper-wire. Two Dutch men were fighting over a nic ...

  2. 【01背包变形】Robberies HDU 2955

    http://acm.hdu.edu.cn/showproblem.php?pid=2955 [题意] 有一个强盗要去几个银行偷盗,他既想多抢点钱,又想尽量不被抓到.已知各个银行 的金钱数和被抓的概率 ...

  3. PHP建立和删除目录

    <?php/*linux中的文件权限filedir 用户 组 其它 rwx rwx rwx 读写执行 6 4 6 读写 读 读写 7 7 7 rw_ r__ rw_ r__ _w_ ___ r ...

  4. Linux(1):基本配置

    linux里面的网络(网卡)配置: 1. 输出 setup 命令进行设置 2. 选择 "Network configuration" ,按 回车键 3. 选择 "Devi ...

  5. 运行hadoop自带的计算圆周率异常

    运行hadoop2 自带的圆周率计算方法时,报错,找了半天,原来是在配置hadoop临时目录时,没有给权限,找到配置的hadoop临时目录文件夹,修改权限即可 Application applicat ...

  6. Codeforces Round #296 (Div. 2) C. Glass Carving [ set+multiset ]

    传送门 C. Glass Carving time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  7. 从零开始写STL—哈希表

    static const int _stl_num_primes = 28; template<typename T, typename Hash = xhash<T>> cl ...

  8. Python从文件中读取字符串,用正则表达式匹配中文字符的问题

    2013-07-27 21:01:37|           在Windows下,用Python从.txt文件中读取字符串,并用正则表达式匹配中文,在网上看了方法,用的时候发现中文没有被匹配.     ...

  9. HDU 2059 【DP】

    题意: 中文. 思路: 这题不是自己的思想. 当对第i个点的最优值进行求解的时候一定存在最后一个加油的点j.这里j直接枚举. 另外将0和n+1个加油站定义为起点和终点. dp需要加强训练. #incl ...

  10. babel 用法及其 .babelrc 的配置详解,想做前端架构,拒绝一知半解...

    Babel 官方介绍:将 ECMAScript 2015 及其版本以后的 javascript 代码转为旧版本浏览器或者是环境中向后兼容版本的  javascript 代码. 简而言之,就是把不兼容的 ...