Core Animation
**Core Animation**是iOS和OS x 系统中图形渲染和动画的基础引擎,可以用他来给app的视图及其他的可见元素增加动画效果。当使用**Core Animation**产生动画时,**Core Animation**会帮你绘制动画所需要的每一帧,而你要做的只是指定几个动画参数(比如开始和结束的位置)和通知**Core Animation**开始。此时**Core Animation**会使用相应的图形硬件进行快速渲染。这个自动的图形加速渲染会产生高帧率和流畅的动画而不增加cpu的负荷及减缓app的运行速度。
其实**Core Animation** 不只是可以用来做动画,动画只是它作用的冰山一角。**Core Animation ** 是一个复合的引擎 。它的职责就是尽快组合屏幕上不同的可视内容,这些内容是被分解成独立的图层存储在一个叫图层树的体系之中。
layer Core Animation 的基础
------------------------------------
在iOS当中,所有的视图都从一个叫做UIVIew的基类派生而来,UIView可以处理触摸事件,可以支持基于Core Graphics绘图,可以做仿射变换(例如旋转或者缩放),或者简单的类似于滑动或者渐变的动画。
Layer ,图层与UIView 类似。也是一些被层级关系管理的矩形块。同样也可以包含一些内容,管理子图层,做动画和变化。但是,图层对象不能处理用处理用户交互,这也它与UIView最大的不同。
每一个视图都有自己的图层对象。也就是Backing layer. 图层会把View的内容捕获被存储在一张bitmap中以便使用硬件来进行相应的操作。通常Layer 被用来当作管理相应View内容的一种方式(当然你可以根据需要创建独立的Layer对象).而视图的职责就是创建并管理这个图层,以确保当视图在层级关系中被添加或移除时对应的图层在相应的层级关系中进行相同的操作。
实际上这些背后关联的图层才是真正用来在屏幕上显示和做动画,UIView仅仅是对它的一个封装,提供了一些iOS类似于处理触摸的具体功能,以及Core Animation底层方法的高级接口。
但是为什么iOS要基于UIView和CALayer提供两个平行的层级关系呢?为什么不用一个简单的层级来处理所有事情呢?原因在于要做职责分离,这样也能避免很多重复代码。在iOS和Mac OS两个平台上,事件和用户交互有很多地方的不同,基于多点触控的用户界面和基于鼠标键盘有着本质的区别,这就是为什么iOS有UIKit和UIView,但是Mac OS有AppKit和NSView的原因。他们功能上很相似,但是在实现上有着显著的区别。我们可以把用一个小范围的mv模式来理解。Layer
就是一个DataObject,当View发生属性数据的改变时会通知Layer去做相应的改变并显示,自己只处理与用户的交互。
视图可以响应事件图层不能响应,但在内容处理方面,图层有更多的View不具备的功能。
1. 边框(borer) ,圆角(Corner),阴影(shadow)
2. 3D变换
3. 非矩形区域
4. 透明遮罩
5. 多级非线性动画。
这些会慢慢解释。
视图与图层的几何属性
----------------------------
当我们改变Layer的一些属性时,改变的只是这个Layer的一些状态信息。当一个改变触发动画时,Layer会把自己缓冲的bitMap跟状态信息交给图形硬件来跟据新的状态信息渲染新的bitmap。图形硬件的渲染速度远远快于软件的渲染速度。下图展示了绘制的过程
由于Layer改变的是一张静态的bitmap,因此大不同于传统的绘制技术。当基于view的改变发生时会调用view的DrawRect: 方法用新的参数重新绘制。但这种绘制是在主线程是发的,并且会消耗cpu。
layer一些可以改变的属性:
简单的可变属性:Frame, bounds,center,position
--------------------------------------------------------
UIView *view = [[UIView alloc] initWithFrame: CGRectMake(10, 10, 40, 50)];
view.backgroundColor = [UIColor redColor];
CALayer *layer = view.layer;
[self.view addSubview:view];
NSLog(@"view‘s frame = %@, view‘s bound = %@ view‘s center = %@",NSStringFromCGRect(view.frame),NSStringFromCGRect(view.bounds),NSStringFromCGPoint(view.center));
NSLog(@"layer‘s frame = %@, layer‘s bound = %@ , layer‘s position = %@",NSStringFromCGRect(layer.frame),NSStringFromCGRect(layer.bounds),NSStringFromCGPoint(layer.position));
结果:view‘s frame = {{10, 10}, {40, 50}}, view‘s bound = {{0, 0}, {40, 50}} view‘s center = {30, 35}
layer‘s frame = {{10, 10}, {40, 50}}, layer‘s bound = {{0, 0}, {40, 50}} , layer‘s position = {30, 35}
从上面的结果我们可以看出,视图跟图层对象都具有frame,跟bound属性。Frame是相对于父视图/图层而言的,是一种相对关系。左上角为(0,0)点。Bound 是相对于自身的属性。表示自己的几何形状。
center是视图的相对于父视图的中心坐标.
positon是图层相对于父图层的中心坐标