####导语ios
说一下为何写这一系列的文章,笔者以前看到动画就以为头大,被CALayer、Transform等名词弄的晕头转向,也查了许多资料,但大部分的资料都是以一个具体的例子来讲明动画的使用,涉及到不少具体的东西,而对不少基本的概念,动画宏观方面的阐述的比较少,因此想写下这一系列的文章,让初学动画的人有个快速的宏观认识。编程
###一、iOS的绘图系统都有哪些呢?api
iOS主要的绘图系统有UIKit、Core Graphics(也称Quartz 2D)、Core Animation、Core Image、OpenGL ES。每个都主要起什么做用呢?大概介绍一下。性能优化
###二、视图绘制与视图布局的区别有哪些呢?app
咱们先来理解一下视图绘制周期的概念,这有助于理解视图绘制与视图布局的区别。工具
视图绘制,是调用UIView中的drawRect方法。若是一个视图调用setNeedsDisplay方法,它就被标记为从新绘制,而且会在下一次绘图周期中从新绘制,也就是会自动调用drawRect方法。oop
视图布局,是调用UIView中的layoutSubviews方法。若是视图中的子视图布局发生变化,须要从新排列,UIKit会自动调用setNeedsLayout方法,也就是对于发生变化的视图逐层次调用layoutSubviews方法。好比frame发生变化、滚动视图等。布局
在画图的时候,咱们应该尽可能避免绘制,多使用布局,这是为何呢?由于布局使用的是GPU(GPU基于硬件进行布局的),而绘制使用的是CPU(基于软件进行绘制的)。性能
补充:CPU VS GPU字体
何时会调用绘制,何时调用布局呢?我本身的理解是这样的,视图在第一次建立的时候,绘制和布局的都会调用的。若是子视图由于一些条件的改变,形成布局的改变,这个时候,系统会自动调用layoutSubviews方法。尽可能避免调用setNeedsDisplay方法。
###三、理解绘图系统中的坐标系
绘图系统中主要使用两种坐标系。
基于点的坐标
原点位于图层的左上角,向右为x轴的正方向,向下为y轴的正方向,一个点的x、y坐标以点为单位。
单位坐标系
原点位于图层的左上角,向右为x轴的正方向,向下为y轴的正方向,一个点的x、y坐标以相对x轴、y轴的比例为值,取值范围为[0, 1]。锚点(anchorPoint)使用单位坐标系。
锚点决定了动画在变化时,z轴的位置。关于锚点的具体做用,坐标变换的具体内容,能够参考下面的两篇文章:
###四、管理图形上下文
图形上下文是什么意思呢?好比,咱们要画一幅画,须要有一张画布的,而后在画布上绘制出一幅画来,图形上下文就和画布的概念同样的。在图形上下文中包含了大量信息,好比设置画笔的颜色、设置文本的字体、设置变形等等。
咱们在使用drawRect方法进行绘制的时候,咱们并无建立CGContext,可是咱们却能够画出来本身想要的东西,这是由于,在调用drawRect方法以前,系统为咱们默认建立了一个图形上下文(CGContext)。
咱们在绘图中常常会遇见这几个名词,CGContextSaveGState和CGContextRestoreGState,UIGraphicsPushContext和UIGraphicsPopContext,咱们来分别介绍一下。
[[UIColor redColor] setFill]; CGContextSaveGState(UIGraphicsGetCurrentContext()); [[UIColor blackColor] setFill]; CGContextRestoreGState(UIGraphicsGetCurrentContext()); UIRectFill(CGRectMake(10, 10, 100, 100));
这段代码设置了画笔的颜色为红色,并保存图形上下文,以后将画笔的颜色改为黑色,并恢复图形上下文。那么最后的画笔颜色是红色仍是黑色的呢?答案是红色的,经过这段代码能看出来CGContextSaveGState和CGContextRestoreGState的用法。
[[UIColor redColor] setFill]; UIGraphicsPushContext(UIGraphicsGetCurrentContext()); [[UIColor blackColor] setFill]; UIGraphicsPopContext(); UIRectFill(CGRectMake(10, 10, 100, 100));
看下此处的代码,经过运行,咱们发现最后画笔的颜色为黑色,这说明UIGraphicsPushContext并无保存图形上下文的信息,那么它的做用是什么呢?假如你正在图形上下文中绘制什么东西,若是这时想要在位图上下文中绘制彻底不一样的内容,这就是UIGraphicsPushContext的做用了,切换到一个新的位图上。当你在新的位图上,绘制完想要的东西后,在经过UIGraphicsPopContext将刚才的图形上下文出栈,也就是恢复到刚才的绘图状态。
切换到另一个上下文,这是一个比较常见的操做,由于经常使用性,系统api提供了UIGraphicsBeginImageContext的快捷方式,它负责将旧的上下文入栈、为新上下文分配内存、建立新的上下文、翻转坐标系统,并使其做为当前上下文使用。
###五、 透明、不透明、隐藏
视图上有三个比较容易混淆的属性:alpha(透明)、opaque(不透明)和hidden(隐藏)。下面就进行一下深刻的区分。
alpha属性决定了视图会经过像素显示多少信息。alpha为1表示全部的视图信息都在像素上表现出来,而alpha为0表示没有视图信息能在像素上表示出来。
opaque,将视图标记为opaque,即是向绘图系统许诺即将绘制的每个像素都要使用全不透明的颜色,这便容许绘图系统忽略被覆盖在下面的视图,这样能够改善性能,尤为是在进行变形的时候。与opaque紧密相关的是clearsContextBeforeDrawing。它的默认值是YES,会在调用drawRect以前将上下问设置为透明黑底。这样会避免视图中产生的任何垃圾数据。
hidden为YES的话,表示视图根本不会被绘制。
隐藏和透明视图不接受触摸事件,若是想建立一个透明视图而且接受触摸事件,能够这样来进行设置,设置它的alpha为一、opaque为NO且backgroundColor为你活[UIColor clearColor],来接手触摸事件。
###六、 绘图工具神器 下面介绍一款绘图神器(PaintCode) 安装完成后,打开工具,界面以下:
在顶部的菜单栏,提供了一些常见的形状,好比矩形、五角星、多边形。咱们以五角星为例,简单介绍一下其用法。拖动五角星到Canvas上,效果以下:
咱们还为其设置了填充颜色为红色的。接下来就是要把作好的图转换成代码导出来,能够在视图下方选择要导出的代码类型,效果以下:
咱们能够看下导出类的源码是怎么样的,以下图:
该怎么在本身的工程中使用呢?咱们只须要在本身的工程中建立一个UIView,在UIView的drawRect方法,调用其提供的方法便可。以下所示:
至此本文结束了,下一篇将经过两个示例来展现怎么具体使用UIKit与CoreGraphics进行绘制。
参考文章连接: