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對(duì)象是組織在三維空間的2d層面
  2. 跟view一樣登疗,layer管理幾何,內(nèi)容和可視屬性炊汹,view跟layer不一樣的時(shí)候岗宣,layer管理圍繞一個(gè)位圖的狀態(tài)信息弹沽。
  3. layer作為一個(gè)model是因?yàn)樗芾淼氖莇ata业稼!

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并用位圖緩存赤兴。動(dòng)畫觸發(fā)時(shí)腔稀,動(dòng)畫把layer狀態(tài)信息和位圖交給硬件,渲染位圖幽勒。

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


basics_layer_rendering_2x.png

layer是控制靜態(tài)位圖嗜侮,相對(duì)于view-base的繪制技術(shù),view-base每次使用新的參數(shù)來調(diào)用drawrect來重新繪制啥容,這是發(fā)生在cpu的
mainthread,而且耗性能锈颗,layer操作緩存的bitmap來用硬件渲染,也會(huì)達(dá)到同樣效果咪惠。

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

有兩種坐標(biāo)系統(tǒng)

  • 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中點(diǎn)的點(diǎn),他是其中一個(gè)根據(jù)anchorpoint的值而發(fā)生改變的值

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是由原作標(biāo)經(jīng)過一個(gè)4緯矩陣變換后得到的坐標(biāo)遥昧,Core Animation已經(jīng)為我們提供了全面的包括creating scale, translation, and rotation matrices and for doing matrix comparisons


transform_basic_math_2x.png

各種變換的矩陣實(shí)現(xiàn)


transform_manipulations_2x.png

三種layer樹

  • Objects in the model layer tree (or simply “l(fā)ayer 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層級(jí)

sublayer_hierarchy_2x-2.png

一般的基本操作都在model layer tree上面覆醇,每個(gè)model layer都有相關(guān)聯(lián)的presentation tree和render tree,presentation tree 一般用于動(dòng)畫展示炭臭,可以用 presentationLayer獲取動(dòng)畫過程中的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獲取的是動(dòng)畫即使的屬性永脓,而layer tree 反應(yīng)的是動(dòng)畫的最終屬性和狀態(tài)

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

因?yàn)閘ayer就是一個(gè)bitmap image的容器鞋仍,可以直接賦值content添加圖片常摧,CGImageRef類型的,當(dāng)用layer設(shè)置圖片時(shí)威创,要注意contentsScale 這個(gè)值落午,在點(diǎn)坐標(biāo)系中,一個(gè)點(diǎn)對(duì)應(yīng)contentsScale個(gè)pixel肚豺,給uiview設(shè)置圖片contentsScale是自動(dòng)適應(yīng)屏幕的溃斋,給layer設(shè)置圖片則需要設(shè)置scale

Using a Delegate to Provide the Layer’s Content

代理方法

  • displayLayer:
  • drawLayer:inContext:,如果代理實(shí)現(xiàn)了displayLayer:就不會(huì)實(shí)現(xiàn)這個(gè)方法。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

當(dāng)又要圓角又要shadow的時(shí)候吸申,maskToBounds會(huì)把陰影切掉盐类,可以使用兩個(gè)layer來實(shí)現(xiàn)

Animating Layer Content

  • implicit animations 隱式動(dòng)畫 改變layer的屬性
  • explicit animation 顯式動(dòng)畫 使用CABaseAnimation等實(shí)現(xiàn),不會(huì)改變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.

隱式動(dòng)畫不可以停止

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
如果立即移除動(dòng)畫在跳,layer會(huì)根據(jù)之前的屬性繪制layer,會(huì)造成畫面突然跳動(dòng)到動(dòng)畫開始的layer的現(xiàn)象隐岛,可以通過presentation樹來獲取停止前的屬性值

Animating Multiple Changes Together

  • CAAnimationGroup
  • 動(dòng)畫事務(wù)猫妙,更強(qiáng)大

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

如果一個(gè)動(dòng)畫的開始再另一個(gè)動(dòng)畫的結(jié)束,最好不要用上面的方法聚凹,可以根據(jù)動(dòng)畫開始和結(jié)束的時(shí)間

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

坐標(biāo)轉(zhuǎn)換

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

時(shí)間轉(zhuǎn)換割坠。

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.
每個(gè)layer都有自己的時(shí)間空間齐帚,但不同layer的這些時(shí)間一般都是同步的,除非設(shè)置了layer的動(dòng)畫速度彼哼,此時(shí)可用時(shí)間轉(zhuǎn)換函數(shù)


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.
    每個(gè)layer的時(shí)間都是相近的
    layer’s speed property causes the duration of animations on that layer (and its sublayers) to change proportionally.
    speed可以改變layer的時(shí)間系統(tǒng)

  • 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.
    可以用上面這兩個(gè)函數(shù)轉(zhuǎn)換時(shí)間系統(tǒng)不同的layer的時(shí)間

  • 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可以獲取標(biāo)準(zhǔn)的時(shí)間对妄,可以用來計(jì)算當(dāng)前l(fā)ayer的時(shí)間

CFTimeInterval localLayerTime = [myLayer convertTime:CACurrentMediaTime() fromLayer:nil];
  • 兩個(gè)動(dòng)畫銜接用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];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市敢朱,隨后出現(xiàn)的幾起案子剪菱,更是在濱河造成了極大的恐慌,老刑警劉巖拴签,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孝常,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蚓哩,警方通過查閱死者的電腦和手機(jī)构灸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岸梨,“玉大人喜颁,你說我怎么就攤上這事〔芾” “怎么了半开?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長次兆。 經(jīng)常有香客問我,道長锹锰,這世上最難降的妖魔是什么芥炭? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮恃慧,結(jié)果婚禮上园蝠,老公的妹妹穿的比我還像新娘。我一直安慰自己痢士,他們只是感情好彪薛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著怠蹂,像睡著了一般善延。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上城侧,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天易遣,我揣著相機(jī)與錄音,去河邊找鬼嫌佑。 笑死豆茫,一個(gè)胖子當(dāng)著我的面吹牛侨歉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播揩魂,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼幽邓,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了火脉?” 一聲冷哼從身側(cè)響起牵舵,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎忘分,沒想到半個(gè)月后棋枕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妒峦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年重斑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肯骇。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡窥浪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出笛丙,到底是詐尸還是另有隱情漾脂,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布胚鸯,位于F島的核電站骨稿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏姜钳。R本人自食惡果不足惜坦冠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望哥桥。 院中可真熱鬧辙浑,春花似錦、人聲如沸拟糕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽送滞。三九已至侠草,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間犁嗅,已是汗流浹背梦抢。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留愧哟,地道東北人奥吩。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓哼蛆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親霞赫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子腮介,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容