CAShapeLayer大法(未完)

Author Avatar
纸简书生 4月 06, 2017

好久都没有研究iOS动画了,昨天看到了一个不规则view。当时就想应该是用CAShapeLayer做的。于是这里回顾一下CAShapeLayer、CADisplayLink、UIBezierPath,mask。

前言

关于iOS动画,已经有许许多多的例子和博客写过。这里也只是复习一下,如果深入了解。可以看一看业界一本公认的动画书籍iOS Core Animation Advanced Techniques。里面的示例代码也有源码地址在CoreAnimationCode

几个类的说明

  • A CADisplayLink object is a timer object that allows your application to synchronize its drawing to the refresh rate of the display

  • 大致有以下几点需要注意。

    1. CADisplayLink是一个能让我们以和屏幕刷新率相同的频率将内容画到屏幕上的定时器
    2. 一但 CADisplayLink 以特定的模式注册到runloop之后,每当屏幕需要刷新的时候,runloop就会调用CADisplayLink绑定的target上的selector,这时target可以读到 CADisplayLink 的每次调用的时间戳,用来准备下一帧显示需要的数据。
    3. 可以通过pause属性开控制CADisplayLink的运行。当我们想结束一个CADisplayLink的时候,应该调用-(void)invalidate从runloop中删除并删除之前绑定的 target跟selector
    4. CADisplayLink 不能被继承。
  • 附带提一下和与 NSTimer 有什么不同

    1. NSTimer的精确度就显得低了点,比如NSTimer的触发时间到的时候,runloop如果在阻塞状态,触发时间就会推迟到下一个runloop周期。并且 NSTimer新增了tolerance属性,让用户可以设置可以容忍的触发的时间的延迟范围。
    2. CADisplayLink使用场合相对专一,适合做UI的不停重绘,比如自定义动画引擎或者视频播放的渲染。
    3. NSTimer的使用范围要广泛的多,各种需要单次或者循环定时处理的任务都可以使用。

UIBezierPath

  • The UIBezierPath class lets you define a path consisting of straight and curved line segments and render that path in your custom views. You use this class initially to specify just the geometry for your path. Paths can define simple shapes such as rectangles, ovals, and arcs or they can define complex polygons that incorporate a mixture of straight and curved line segments. After defining the shape, you can use additional methods of this class to render the path in the current drawing context.

建议先看看iOS UIBezierPath类 介绍

UIBezierPath类可以创建基于矢量的路径,它是Core Graphics框架关于CGPathRef类型数据的封装,利用它创建直线或者曲线来构建我们想要的形状,每一个直线段或者曲线段的结束位置就是下一个线段开始的地方。这些连接的直线或者曲线的集合成为subpath。一个UIBezierPath对象的完整路径包括一个或者多个subpath。

使用步骤:

  1. 创建一个Bezier Path对象。
  2. 使用方法moveToPoint:去设置初始线段的起点。
  3. 添加line或者curve去定义一个或者多个subpath。
  4. 修改UIBezierPath对象跟绘图相关的属性。

CAShapeLayer

  • A layer that draws a cubic Bezier spline in its coordinate space

建议先看看CAShapeLayer

CAShapeLayer是一个通过矢量图形而不是bitmap来绘制的图层子类。CAShapeLayer可以用来绘制所有通过CGPath来表示的形状,上面讲到了可以用UIBezierPath来创建任何你想要的路径,使用CAShapeLayer的属性path配合UIBezierPath创建的路径,就可以呈现出我们想要的形状。

这个形状不一定要闭合,图层路径也不一定是连续不断的,你可以在CAShapeLayer的图层上绘制好几个不同的形状,但是你只有一次机会去设置它的path、lineWith、lineCap等属性,如果你想同时设置几个不同颜色的多个形状,你就需要为每个形状准备一个图层。

mask

  • An optional layer whose alpha channel is used to mask the layer’s content.
  • The layer’s alpha channel determines how much of the layer’s content and background shows through. Fully or partially opaque pixels allow the underlying content to show through but fully transparent pixels block that content.

建议先看看图层蒙板

CALayer有一个属性叫做mask,通常被称为蒙版图层,这个属性本身也是CALayer类型,有和其他图层一样的绘制和布局属性。它类似于一个子视图,相对于父图层(即拥有该属性的图层)布局,但是它却不是一个普通的子视图。不同于一般的subLayer,mask定义了父图层的可见区域,简单点说就是最终父视图显示的形态是父视图自身和它的属性mask的交集部分。

mask图层的color属性是无关紧要的,真正重要的是它的轮廓,mask属性就像一个切割机,父视图被mask切割,相交的部分会留下,其他的部分则被丢弃。

CALayer的蒙版图层真正厉害的地方在于蒙版图层不局限于静态图,任何有图层构成的都可以作为mask属性,这意味着蒙版可以通过代码甚至是动画实时生成。

实际例子

TODO

扩展阅读

动画黄金搭档:CADisplayLink & CAShapeLayer
关于CAShapeLayer的一些实用案例和技巧
放肆地使用UIBezierPath和CAShapeLayer画各种图形