Core Animation Programming Guide

Core Animation Basics

Layers Provide the Basis for Drawing and Animations

Layer objects are 2D surfaces organized in a 3D space and are at the heart of everything you do with Core Animation. Like views, layers manage information about the geometry, content, and visual attributes of their surfaces. Unlike views, layers do not define their own appearance. A layer merely manages the state information surrounding a bitmap. The bitmap itself can be the result of a view drawing itself or a fixed image that you specify. For this reason, the main layers you use in your app are considered to be model objects because they primarily manage data. This notion is important to remember because it affects the behavior of animations.

  1. layer对象是组织在三维空间的2d层面
  2. 跟view一样,layer管理几何,内容和可视属性,view跟layer不一样的时候,layer管理围绕一个位图的状态信息。
  3. layer作为一个model是因为它管理的是data!

The Layer-Based Drawing Model

Most layers do not do any actual drawing in your app. Instead, a layer captures the content your app provides and caches it in a bitmap, which is sometimes referred to as the backing store. When you subsequently change a property of the layer, all you are doing is changing the state information associated with the layer object. When a change triggers an animation, Core Animation passes the layer’s bitmap and state information to the graphics hardware, which does the work of rendering the bitmap

  1. layer捕获app提供的content并用位图缓存。动画触发时,动画把layer状态信息和位图交给硬件,渲染位图。

Manipulating the bitmap in hardware yields much faster animations than could be done in software.


basics_layer_rendering_2x.png

layer是控制静态位图,相对于view-base的绘制技术,view-base每次使用新的参数来调用drawrect来重新绘制,这是发生在cpu的
mainthread,而且耗性能,layer操作缓存的bitmap来用硬件渲染,也会达到同样效果。

Layer-Based Animations

The data and state information of a layer object is decoupled from the visual presentation of that layer’s content onscreen

basics_animation_types_2x.png

During the course of an animation, Core Animation does all of the frame-by-frame drawing for you in hardware. All you have to do is specify the start and end points of the animation and let Core Animation do the rest. You can also specify custom timing information and animation parameters as needed; however, Core Animation provides suitable default values if you do not.

layer_coords_bounds_2x.png
layer_coords_unit_2x.png

有两种坐标系统

  • point-based coordinate systems

Point-based coordinates are used when specifying values that map directly to screen coordinates or must be specified relative to another layer, such as for the layer’s position property.

  • unit coordinate systems

Unit coordinates are used when the value should not be tied to screen coordinates because it is relative to some other value. For example, the layer’s anchorPoint property specifies a point relative to the bounds of the layer itself, which can change.

上图中,position是在layer中点的点,他是其中一个根据anchorpoint的值而发生改变的值

Anchor Points Affect Geometric Manipulations

layer_coords_anchorpoint_position_2x.png
layer_coords_anchorpoint_transform_2x.png

Layers Can Be Manipulated in Three Dimensions

The transform property of CALayer specifies the transforms that you want to apply both to the layer and its embedded sublayers.

transform是由原作标经过一个4纬矩阵变换后得到的坐标,Core Animation已经为我们提供了全面的包括creating scale, translation, and rotation matrices and for doing matrix comparisons


transform_basic_math_2x.png

各种变换的矩阵实现


transform_manipulations_2x.png

三种layer树

  • Objects in the model layer tree (or simply “layer tree”) are the ones your app interacts with the most. The objects in this tree are the model objects that store the target values for any animations.

  • Objects in the presentation tree contain the in-flight values for any running animations.

  • Objects in the render tree perform the actual animations and are private to Core Animation.

layer层级

sublayer_hierarchy_2x-2.png

一般的基本操作都在model layer tree上面,每个model layer都有相关联的presentation tree和render tree,presentation tree 一般用于动画展示,可以用 presentationLayer获取动画过程中的layer属性

sublayer_hierarchies_2x.png

Important: You should access objects in the presentation tree only while an animation is in flight. While an animation is in progress, the presentation tree contains the layer values as they appear onscreen at that instant. This behavior differs from the layer tree, which always reflects the last value set by your code and is equivalent to the final state of the animation.
presentation tree获取的是动画即使的属性,而layer tree 反应的是动画的最终属性和状态

Layers do not handle events, draw content, participate in the responder chain,


Setting Up Layer Objects

Changing the Layer Object Associated with a View

Changing the Layer Class Used by UIView

改变UIView的layer,可以重写

+ (Class) layerClass {
   return [CAMetalLayer class];
}

CALayer子类

18996C7D-FF41-4AE5-B993-6C3FED8A8288.png

Providing a Layer’s Contents

A layer’s content consists of a bitmap containing the visual data you want to display. You can provide the content for that bitmap in one of three ways:

  • Assign an image object directly to the layer object’s contents property. (This technique is best for layer content that never, or rarely, changes.)
  • Assign a delegate object to the layer and let the delegate draw the layer’s content. (This technique is best for layer content that might change periodically and can be provided by an external object, such as a view.)
  • Define a layer subclass and override one of its drawing methods to provide the layer contents yourself. (This technique is appropriate if you have to create a custom layer subclass anyway or if you want to change the fundamental drawing behavior of the layer.)

Using an Image for the Layer’s Content

因为layer就是一个bitmap image的容器,可以直接赋值content添加图片,CGImageRef类型的,当用layer设置图片时,要注意contentsScale 这个值,在点坐标系中,一个点对应contentsScale个pixel,给uiview设置图片contentsScale是自动适应屏幕的,给layer设置图片则需要设置scale

Using a Delegate to Provide the Layer’s Content

代理方法

  • displayLayer:
  • drawLayer:inContext:,如果代理实现了displayLayer:就不会实现这个方法。Core Animation creates a bitmap, creates a graphics context to draw into that bitmap, and then calls your delegate method to fill the bitmap. All your delegate method has to do is draw into the provided graphics context.

Providing Layer Content Through Subclassing

  • override the layer’s display method and use it to set the contents property of the layer directly.
  • Override the layer’s drawInContext: method and use it to draw into the provided graphics context.

Tweaking the Content You Provide

positioningmask_2x.png

Working with High-Resolution Images

Changing the value of the contentsScale property is only necessary if you are assigning a bitmap to your layer directly.

Adjusting a Layer’s Visual Style and Appearance

Layers Have Their Own Background and Border

layer_border_background_2x.png

Layers Support a Corner Radius

layer_corner_radius_2x.png

Because it involves applying a transparency mask, the corner radius does not affect the image in the layer’s contents property unless the masksToBounds property is set to YES

Layers Support Built-In Shadows

The opacity value for layer shadows is set to 0 by default, which effectively hides the shadow. Changing the opacity to a nonzero value causes Core Animation to draw the shadow

当又要圆角又要shadow的时候,maskToBounds会把阴影切掉,可以使用两个layer来实现

Animating Layer Content

  • implicit animations 隐式动画 改变layer的属性
  • explicit animation 显式动画 使用CABaseAnimation等实现,不会改变layer最终的属性值,you must also update the layer’s property as shown in the preceding example.

Implicit and explicit animations normally begin executing after the current run loop cycle ends, and the current thread must have a run loop in order for animations to be executed.

Using a Keyframe Animation to Change Layer Properties

Specifying Keyframe Values

  • For properties that take a CGRect (such as the bounds and frame properties), wrap each rectangle in an NSValue object.
  • For the layer’s transform property, wrap each CATransform3D matrix in an NSValue object. Animating this property causes the keyframe animation to apply each transform matrix to the layer in turn.
  • For the borderColor property, cast each CGColorRef data type to the type id before adding it to the array.
  • For properties that take a CGFloat value, wrap each value in an NSNumber object before adding it to the array.
    When animating the layer’s contents property, specify an array of CGImageRef data types.

Specifying the Timing of a Keyframe Animation

The calculationMode property defines the algorithm to use in calculating the animation timing.

  • Linear and cubic animations—that is, animations where the calculationMode property is set to kCAAnimationLinear or kCAAnimationCubic—use the provided timing information to generate the animation. These modes give you the maximum control over the animation timing.
  • Paced animations—that is, animations where the calculationMode property is set to kCAAnimationPaced or kCAAnimationCubicPaced—do not rely on the external timing values provided by the keyTimes or timingFunctions properties. Instead, timing values are calculated implicitly to provide the animation with a constant velocity.
  • Discrete animations—that is, animations where the calculationMode property is set to kCAAnimationDiscrete—cause the animated property to jump from one keyframe value to the next without any interpolation(插值). This calculation mode uses the values in the keyTimes property but ignores the timingFunctions property

Stopping an Explicit Animation While It Is Running

  • To remove a single animation object from the layer, call the layer’s removeAnimationForKey:method to remove your animation object. This method uses the key that was passed to the addAnimation:forKey:method to identify the animation. The key you specify must not be nil.
  • To remove all animation objects from the layer, call the layer’s removeAllAnimations method. This method removes all ongoing animations immediately and redraws the layer using its current state information.

隐式动画不可以停止

When you remove an animation from a layer, Core Animation responds by redrawing the layer using its current values. Because the current values are usually the end values of the animation, this can cause the appearance of the layer to jump suddenly. If you want the layer’s appearance to remain where it was on the last frame of the animation, you can use the objects in the presentation tree to retrieve those final values and set them on the objects in the layer tree
如果立即移除动画,layer会根据之前的属性绘制layer,会造成画面突然跳动到动画开始的layer的现象,可以通过presentation树来获取停止前的属性值

Animating Multiple Changes Together

  • CAAnimationGroup
  • 动画事务,更强大

Detecting the End of an Animation

There are two different ways to be notified about the state of an animation:

  • Add a completion block to the current transaction using the setCompletionBlock: method. When all of the animations in the ``transaction finish, the transaction executes your completion block.
  • Assign a delegate to your CAAnimation object and implement the animationDidStart:andanimationDidStop:finished: delegate methods.

If you want to chain two animations together so that one starts when the other finishes, do not use animation notifications. Instead, use the beginTime property of your animation objects to start each one at the desired time. To chain two animations together, set the start time of the second animation to the end time of the first animation. For more information about animation and timing values, see Customizing the Timing of an Animation

如果一个动画的开始再另一个动画的结束,最好不要用上面的方法,可以根据动画开始和结束的时间

Rules for Modifying Layers in iOS

[UIView animateWithDuration:1.0 animations:^{
   // Change the opacity implicitly.
   myView.layer.opacity = 0.0;
 
   // Change the position explicitly.
   CABasicAnimation* theAnim = [CABasicAnimation animationWithKeyPath:@"position"];
   theAnim.fromValue = [NSValue valueWithCGPoint:myView.layer.position];
   theAnim.toValue = [NSValue valueWithCGPoint:myNewPosition];
   theAnim.duration = 3.0;
   [myView.layer addAnimation:theAnim forKey:@"AnimateFrame"];
}];

Both animations start at the same time but the opacity animation runs with the default timing while the position animation runs with the timing specified in its animation object.

Remember to Update View Constraints as Part of Your Animation


Building a Layer Hierarchy

Arranging Layers into a Layer Hierarchy

Adding, Inserting, and Removing Sublayers

屏幕快照 2016-11-14 上午1.09.39.png

When adding and inserting sublayers, you must set the size and position of the sublayer before it appears onscreen. You can modify the size and position of a sublayer after adding it to your layer hierarchy but should get in the habit of setting those values when you create the layer.

Positioning and Sizing Sublayers

You set the size of a sublayer using the bounds property and set its position within its superlayer using the position property. The origin of the bounds rectangle is almost always (0, 0) and the size is whatever size you want for the layer specified in points. The value in the position property is interpreted relative to the layer’s anchor point, which is located in the center of the layer by default. If you do not assign values to these properties, Core Animation sets the initial width and height of the layer to 0 and sets the position to (0, 0).

myLayer.bounds = CGRectMake(0, 0, 100, 100);
myLayer.position = CGPointMake(200, 200);
`Important: Always use integral numbers for the width and height of your layer.`

Sublayers and Clipping

clipping_2x.png

Converting Coordinate Values Between Layers

坐标转换

  • convertPoint:fromLayer:
  • convertPoint:toLayer:
  • convertRect:fromLayer:
  • convertRect:toLayer:

时间转换。

In addition to converting point and rectangle values, you can also convert time values between layers using the convertTime:fromLayer:and convertTime:toLayer: methods. Each layer defines its own local time space and uses that time space to synchronize the beginning and ending of animations with the rest of the system. These time spaces are synchronized by default; however, if you change the animation speed for one set of layers, the time space for those layers changes accordingly. You can use the time conversion methods to to account for any such factors and ensure that the timing of both layers is synchronized.
每个layer都有自己的时间空间,但不同layer的这些时间一般都是同步的,除非设置了layer的动画速度,此时可用时间转换函数


Advanced Animation Tricks

Customizing the Timing of an Animation

  • CAAimation 遵循CAMediaTiming protocol
  • The CALayer also adopts it so that you can configure some timing-related features for your implicit animations
  • Each layer has its own local time that it uses to manage animation timing. Normally, the local time of two different layers is close enough that you could specify the same time values for each and the user might not notice anything.
    每个layer的时间都是相近的
    layer’s speed property causes the duration of animations on that layer (and its sublayers) to change proportionally.
    speed可以改变layer的时间系统

  • To assist you in making sure time values are appropriate for a given layer, the CALayer class defines the convertTime:romLayer: and convertTime:toLayer: methods.
    可以用上面这两个函数转换时间系统不同的layer的时间

  • CACurrentMediaTime function is a convenience function that returns the computer’s current clock time, which the method takes and converts to the layer’s local time.CACurrentMediaTime可以获取标准的时间,可以用来计算当前layer的时间

CFTimeInterval localLayerTime = [myLayer convertTime:CACurrentMediaTime() fromLayer:nil];
  • 两个动画衔接用begintime

Pausing and Resuming Animations

  • adopt the CAMediaTiming protocol
-(void)pauseLayer:(CALayer*)layer {
   CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
   layer.speed = 0.0;
   layer.timeOffset = pausedTime;
}
 
-(void)resumeLayer:(CALayer*)layer {
   CFTimeInterval pausedTime = [layer timeOffset];
   layer.speed = 1.0;
   layer.timeOffset = 0.0;
   layer.beginTime = 0.0;
   CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
   layer.beginTime = timeSincePause;
}

Explicit Transactions Let You Change Animation Parameters

Only after you commit the changes for the outermost transaction does Core Animation begin the associated animations

[CATransaction begin]; // Outer transaction
 
// Change the animation duration to two seconds
[CATransaction setValue:[NSNumber numberWithFloat:2.0f]
                forKey:kCATransactionAnimationDuration];
// Move the layer to a new position
theLayer.position = CGPointMake(0.0,0.0);
 
[CATransaction begin]; // Inner transaction
// Change the animation duration to five seconds
[CATransaction setValue:[NSNumber numberWithFloat:5.0f]
                 forKey:kCATransactionAnimationDuration];
 
// Change the zPosition and opacity
theLayer.zPosition=200.0;
theLayer.opacity=0.0;
 
[CATransaction commit]; // Inner transaction
 
[CATransaction commit]; // Outer transaction

Adding Perspective to Your Animations

position

Changing a Layer’s Default Behavior

Disable Actions Temporarily Using the CATransaction Class

[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue
                 forKey:kCATransactionDisableActions];
[aLayer removeFromSuperlayer];
[CATransaction commit];
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容