4.1 iOS 核心动画
1.1CALayer概述
(一)官方描述
The CALayer class manages image-based content and allows you to perform animations on that content. Layers are often used to provide the backing store for views but can also be used without a view to display content. A layer’s main job is to manage the visual content that you provide but the layer itself has visual attributes that can be set, such as a background color, border, and shadow. In addition to managing visual content, the layer also maintains information about the geometry of its content (such as its position, size, and transform) that is used to present that content onscreen. Modifying the properties of the layer is how you initiate animations on the layer’s content or geometry. A layer object encapsulates the duration and pacing of a layer and its animations by adopting the CAMediaTiming protocol, which defines the layer’s timing information.
If the layer object was created by a view, the view typically assigns itself as the layer’s delegate automatically, and you should not change that relationship. For layers you create yourself, you can assign a delegate object and use that object to provide the contents of the layer dynamically and perform other tasks. A layer may also have a layout manager object (assigned to the layoutManager property) to manage the layout of subviews separately.
CALayer类管理基于图像的内容并且允许你在这些内容上面执行动画.Layer通常用来存储界面组件,但是它也可以显示界面上的组件.一个layer的主要工作就是管理可视化的内容(程序员定义的UI组件),并且layer也有对应的可视组件的属性能够被设置,比如backgroundcolor,border,shadow等.除了管理这些可视组件之外Layer也维持了这些可视组件的一些几何信息(比如position,size和transform)这些信息确定他们在屏幕上面的位置.修改layer的这些属性你就能够为layer上面的这些可视组件初始化一个动画.一个Layer对象封装了一个layer动画的持续时间和速度,并且实现了CAMediaTiming协议,它定义了layer的时间信息.
如果layer对象被一个view创建,这个view就会自动将自己作为layer的代理,你不能改变这种关系.你也可以为这个layer创建一个自己的代理,并使用该代理对象提供的内容执行其他任务,每一个layer都有一个布局管理对象(layer的layoutManager属性)来分别管理子视图的布局.
(二)CALayer是什么
- 在iOS系统中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮、一个文本标签、一个文本输入框、一个图标等等,这些都是UIView。
- 其实UIView之所以能显示在屏幕上,完全是因为它内部的一个层(CALayer)。
- 在创建UIView对象时,UIView内部会自动创建一个层(即CALayer对象),并且view就会自动将自己作为layer的代理,通过UIView的layer属性可以访问这个层。当UIView需要显示到屏幕上时,会调用drawRect:方法进行绘图,并且会将所有内容绘制在自己的层上,绘图完毕后,系统会将层拷贝到屏幕上,于是就完成了UIView的显示。
- 换句话说:UIView本身不具备显示的功能,是它内部的层才有显示功能。
(三)CALayer作用
1.>可以调整UIView的外观属性,比如阴影,圆角大小,边框的宽度和颜色等.
2.>可以给图层添加动画,实现一些炫酷的功能(后面讲的核心动画就作用在CALayer的可动画属性)
(四)CALayer常用属性
备注:可动画属性:核心动画可以修改这些属性产生动画.
/* The bounds of the layer. Defaults to CGRectZero. Animatable. */
// 影响到View的宽度和高度(可动画属性)
@property CGRect bounds;
/* The position in the superlayer that the anchor point of the layer's
* bounds rect is aligned to. Defaults to the zero point. Animatable. */
// 在父view中的位置,默认是中心点,具体由anchorPoint决定(可动画属性)
@property CGPoint position;
/* Defines the anchor point of the layer's bounds rect, as a point in
* normalized layer coordinates - '(0, 0)' is the bottom left corner of
* the bounds rect, '(1, 1)' is the top right corner. Defaults to
* '(0.5, 0.5)', i.e. the center of the bounds rect. Animatable. */
// 锚点(x,y的范围都是0-1),决定了position的位置(可动画属性)
@property CGPoint anchorPoint;
/* A transform applied to the layer relative to the anchor point of its
* bounds rect. Defaults to the identity transform. Animatable. */
// 变形属性(可动画属性)
@property CATransform3D transform;
/* The background color of the layer. Default value is nil. Colors
* created from tiled patterns are supported. Animatable. */
// 设置layer的背景色(可动画属性)
@property(nullable) CGColorRef backgroundColor;
/* When positive, the background of the layer will be drawn with
* rounded corners. Also effects the mask generated by the
* `masksToBounds' property. Defaults to zero. Animatable. */
// 圆角半径(可动画属性)
@property CGFloat cornerRadius;
/* The width of the layer's border, inset from the layer bounds. The
* border is composited above the layer's content and sublayers and
* includes the effects of the `cornerRadius' property. Defaults to
* zero. Animatable. */
// 边框宽度(可动画属性)
@property CGFloat borderWidth;
/* The color of the layer's border. Defaults to opaque black. Colors
* created from tiled patterns are supported. Animatable. */
// 边框的颜色(可动画属性)
@property(nullable) CGColorRef borderColor;
/** Shadow properties.阴影属性 **/
/* The color of the shadow. Defaults to opaque black. Colors created
* from patterns are currently NOT supported. Animatable. */
// 阴影颜色(可动画属性)
@property(nullable) CGColorRef shadowColor;
/* The opacity of the shadow. Defaults to 0. Specifying a value outside the
* [0,1] range will give undefined results. Animatable. */
// 阴影不透明 取值0:透明 1:表示不透明 默认为0 (可动画属性)
@property float shadowOpacity;
/* The shadow offset. Defaults to (0, -3). Animatable. */
// 阴影偏移量 (可动画属性)
@property CGSize shadowOffset;
/* The blur radius used to create the shadow. Defaults to 3. Animatable. */
// 阴影的模糊半径默认值为3 值越大越模糊 (可动画属性)
@property CGFloat shadowRadius;
/* When non-null this path defines the outline used to construct the
* layer's shadow instead of using the layer's composited alpha
* channel. The path is rendered using the non-zero winding rule.
* Specifying the path explicitly using this property will usually
* improve rendering performance, as will sharing the same path
* reference across multiple layers. Upon assignment the path is copied.
* Defaults to null. Animatable. */
// 阴影路径(可动画属性)
@property(nullable) CGPathRef shadowPath;
(五)position和anchorPoint属性介绍
1.>position属性用来设置CALayer在父层中的位置,以父层的左上角为原点(0,0).
2.>anchorPoint锚点(定位点)决定CALayer上面的那个点会在position所指的位置,以自己的左上角为原点(0,0),x,y取值范围都是0-1,默认值为(0.5,0.5)也就是CALayer的中心点.
动画演示position和anchorPoint属性
(六)CALayer和UIView的选择
CALayer也可以做出和UIView相同的显示效果,那究竟是使用谁来做?
CALayer是不能处理用户事件的,UIView是可以处理用户事件,所以如果显示出来的东西需要和用户交互的话,使用UIView;如果不需要和用户进行交互,用UIView和UILayer都可以.CALayer的性能会高一些,因为它少了事件处理的功能,更加轻量级.
(七)隐式动画
1.>每一个UIView内部都关联了一个CALayer,称这个layer为根层,所有非根层(手动创建的CALayer)都存在着隐式动画
2.>设么是隐式动画?当对自定义的layer部分属性进行修改时,默认会自动产生一些动画效果.
这些属性成为Animatable Properties(可动画属性)
3.>比如下面layer的可动画属性:
* bounds:用于设置CALayer的宽度和高度,修改这个属性会产生缩放动画.
* backgroundColor:用于设置CALAyer的背景色.修改这个属性会产生背景色的渐变动画.
* position:用于设置CALayer的位置,修改这个属性会产生平移动画.
4.>隐式动画是可以关闭的:
/* 可以是用动画事务(CATransaction)关闭隐式动画*/
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.myview.layer.position = CGPointMake(10, 10);
[CATransaction commit];