QuartzCore和CoreAnimation

相關資源

GitHub粒子發(fā)射和復制圖層示例
GitHub粘性控件示例
GitHub彈性動畫
CALayer分析
響應者手勢分析
CAEmitter分析

QuartzCore 簡介

本文檔集合提供了核心動畫的API參考。核心動畫為應用程序提供動畫和顯示層次結構功能。有關詳細信息,請參見 Core Animation Programming Guide

QuartzCore主要結構

  1. CoreAnimation
  2. CADisplayLink定時器
  3. CALayer 及其子類(參考上方鏈接)
  4. CAMediaTiming協(xié)議相關
  5. CATransaction事物相關
  6. CATransform3D

可以看出所有的類和協(xié)議都以CA開頭,所以可以把此框架認為就是核心動畫框架

CoreAnimation簡介

CoreAnimation在APP中的結構.png

核心動畫本身并不是繪圖系統(tǒng)。它是一個在硬件層面合成和操縱您的應用程序的內容的基礎設施。在此基礎設施的核心是CALayer對象,層用于管理和操作內容。一個圖層捕獲你的內容到一個位圖中,位圖可以很容易地被圖形硬件使用。在大多數(shù)應用中,層是用來管理View內容的,但也可以根據(jù)需要創(chuàng)建獨立獨立的層使用。

CoreAnimation基本使用思路
CoreAnimation1.png

其實還有一個孫子類CASpringAnimation,它繼承自CABasicAnimation,是用來做彈性動畫的。其實很多動畫UIKit中也有相關的API(包括彈性動畫),至于使用哪一種動畫:

  1. UIView動畫與核心動畫的區(qū)別?
  • 核心動畫只作用在layer.
  • 核心動畫修改的值都是假像.它的真實位置沒有發(fā)生變化,不會改變layer的frame、transform屬性.
  1. 什么時候用UIView動畫什么時候用核心動畫?
  • 當需要與用戶進行交互時用UIView,不需要與用戶進行交互時兩個都可以。
  1. 什么情況用核心動畫最多?
  • 轉場動畫(UIView的轉場動畫類型比較少).
  • 幀動畫.
  • 動畫組.

CAAnimation使用

所有的核心動畫形式都定義在這個CAAnimation.h頭文件中

開發(fā)步驟:
  1. 首先得有CALayer(因為CoreAnimation是作用在CALayer上的
  2. 初始化一個CAAnimation對象,并設置一些動畫相關屬性
  3. 通過調用CALayer的addAnimation:forKey:方法,增加CAAnimation對象到CALayer中,這樣就能開始執(zhí)行動畫了
  4. 通過調用CALayer的removeAnimationForKey:方法可以停止CALayer中的動畫
CAMediaTiming協(xié)議

簡介:這個協(xié)議對于核心動畫很重要。它提供對動畫節(jié)奏時間的控制的API。 Layers and Animations都遵守并實現(xiàn)了協(xié)議方法。這個協(xié)議建立了分層的定時系統(tǒng)定時系統(tǒng),每個對象描述的時間值都是映射自其parent。
Tip:animation的parent是groupAnimation,再往上是UILayer,再往上是layer.superLayer。下面會舉例一個屬性分析。

CAMediaTiming屬性

/* 動畫開始的時間,所有類型對象的該值都是0,它好像是一個相對值:舉例:假如layer.beginTime = 1,圖層上的動畫animation.beginTime = CACurrentMediaTime() + 2 ,那么這個動畫被加入之后就會延遲1+2=3秒鐘開始執(zhí)行*/
@property CFTimeInterval beginTime;

/* Specifies the basic duration of the animation, in seconds. */
@property CFTimeInterval duration;

/* 運動速度,如果該值是2,那么該動畫的速度將會是parent類的2倍 默認值是 1*/
@property float speed;

/*timeOffset和beginTime類似,但是和增加beginTime導致的延遲動畫不同,增加timeOffset只是讓動畫快進到某一點,例如,對于一個持續(xù)1秒的動畫來說,設置timeOffset為0.5意味著動畫將從一半的地方開始。默認值0 */
@property CFTimeInterval timeOffset;

/* The repeat count of the object. May be fractional. Defaults to 0. */
@property float repeatCount;

/* The repeat duration of the object. Defaults to 0. */
@property CFTimeInterval repeatDuration;

/* 反向執(zhí)行動畫. Defaults to NO. */
@property BOOL autoreverses;

/* 動畫執(zhí)行完事之后,應該怎么處理,如下選項
CA_EXTERN NSString * const kCAFillModeForwards
    CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);
CA_EXTERN NSString * const kCAFillModeBackwards
    CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);
CA_EXTERN NSString * const kCAFillModeBoth
    CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);
CA_EXTERN NSString * const kCAFillModeRemoved
    CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);
 Defaults to 'removed'. */
@property(copy) NSString *fillMode;

CACurrentMediaTime()
Returns the current CoreAnimation absolute time.
這個確實不好理解,不過我們可以通過測試總結:

  1. 他從動畫產生被添加到Layer上記錄一個時間a;
  2. 如果動畫是被beginTime 延遲了2秒,但是它的值是a+=2;
  3. 如果動畫被暫停了3(speed = 0),a還是會按系統(tǒng)時鐘走下去a+=3;
    所以CACurrentMediaTime()這個時間非常關鍵
CALayer上動畫的暫停和恢復
- (void)pauseLayer {
    CALayer *layer = self.redView.layer;
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    // 讓CALayer的時間停止走動
    layer.speed = 0.0;
    // 讓CALayer的時間停留在pausedTime這個時刻
    layer.timeOffset = pausedTime;
}

- (void)resumeLayer {
    CALayer *layer = self.redView.layer;
    CFTimeInterval pausedTime = layer.timeOffset;
    // 1. 讓CALayer的時間繼續(xù)行走
    layer.speed = 1.0;
    // 2. 取消上次記錄的停留時刻
    layer.timeOffset = 0.0;
    // 3. 計算暫停的時間(這里也可以用CACurrentMediaTime()-pausedTime)
    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    // 4. 設置相對于父坐標系的開始時間(往后退timeSincePause)
    NSLog(@"Resume---- %f",timeSincePause);
    layer.beginTime += timeSincePause;
}
CAAnimation

是所有核心動畫對象的父類

/* 動畫節(jié)奏控制,默認線性動畫 */
@property(nullable, strong) CAMediaTimingFunction *timingFunction;

/* 動畫執(zhí)行過程代理 */
@property(nullable, strong) id <CAAnimationDelegate> delegate;

/*動畫執(zhí)行完畢是否從Layer上移除,默認YES;如果不想移除動畫最終狀態(tài),那就設置為NO,不過還要設置fillMode為kCAFillModeForwards
 */
@property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;

// CAAnimationDelegate方法(可選)
/* Called when the animation begins its active duration. */
- (void)animationDidStart:(CAAnimation *)anim;
/* 當動畫完成了它的執(zhí)行時間或者被移除了,這個方法會被調用. 'flag'is true if the animation reached the end of its active duration
 without being removed. */
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
CAPropertyAnimation

CAAnimation的子類,也是個抽象類,要想創(chuàng)建動畫對象,應該使用它的兩個子類:CABasicAnimation和CAKeyframeAnimation

/* 通過指定CALayer的一個屬性名稱為keyPath(NSString類型),并且對CALayer的這個屬性的值進行修改,達到相應的動畫效果。比如,指定@“position”為keyPath,就修改CALayer的position屬性的值,以達到平移的動畫效果 */
@property(nullable, copy) NSString *keyPath;
CABasicAnimation
// keyPath相應屬性的初始值
@property(nullable, strong) id fromValue;
// keyPath相應屬性的結束值
@property(nullable, strong) id toValue;
/ /keyPath相應屬性的過渡值
@property(nullable, strong) id byValue;
CAKeyframeAnimation

關鍵幀動畫,也是CAPropertyAnimation的子類,與CABasicAnimation的區(qū)別是:CAKeyframeAnimation對keyPath可以使用多值,而且支持路線Path

// 里面的元素稱為“關鍵幀”(keyframe)。動畫對象會在指定的時間(duration)內,依次顯示values數(shù)組中的每一個關鍵幀。
@property(nullable, copy) NSArray *values;

/* 可選屬性,定義了動畫功能的行為,非空值就會覆蓋Values屬性*/
@property(nullable) CGPathRef path;

/* 可選,定義了動畫的節(jié)奏(NSNumber類型)。每個值對應values里的每一個值,取值[0,1]。比如:values中有三個值,keyTimes = @[@0.2,@0.5,@0.8],則在duration*0.2開始從value0執(zhí)行動畫,在duration*0.9到value2并等待uration*0.1時間之后結束動畫 */
@property(nullable, copy) NSArray<NSNumber *> *keyTimes;

// 對應values,加入values有n個keyframes,那么就需要n-1個timingFunctions,它描述keyframe到keyframe的時間節(jié)奏。
@property(nullable, copy) NSArray<CAMediaTimingFunction *> *timingFunctions;
CASpringAnimation

彈性動畫,繼承CABasicAnimation

/* 附在彈簧末端的物體的質量。必須大于0,默認值是1. */
@property CGFloat mass;

/* 彈簧剛度系數(shù)。必須大于0, Defaults to 100. */
@property CGFloat stiffness;

/* 阻尼系數(shù), 必須大于或者等于0,Defaults to 10. */
@property CGFloat damping;

/* 附在彈簧上的物體的初速度,默認值0,代表沒有移動;負值表示網固定點反方向運動,正值反之 */
@property CGFloat initialVelocity;

/* 返回彈簧系統(tǒng)在靜止時所需的估計時間。 時間是在當前系數(shù)下預估的。 */
@property(readonly) CFTimeInterval settlingDuration;
CAAnimationGroup

動畫組,動畫組,是CAAnimation的子類,可以保存一組動畫對象,將CAAnimationGroup對象加入層后,組中所有動畫對象可以同時并發(fā)運行,屬性beginTime剛才也提到了,具有累加的效果。

CATransition

轉場動畫,CATransition是CAAnimation的子類,用于做轉場動畫。UINavigationController就是通過CATransition實現(xiàn)了將控制器的視圖推入屏幕的動畫效果。

/* 轉場動畫類型,Defaults to `fade'. */
@property(copy) NSString *type;

/* 轉場動畫子類型 */
@property(nullable, copy) NSString *subtype;

/* The amount of progress through to the transition at which to begin and end execution. Legal values are numbers in the range [0,1]。endProgress(默認值1)值必須要大于startProgress(默認值0)。*/
@property float startProgress;
@property float endProgress;

/* 執(zhí)行過度的可選過濾器,一旦設置`type' and `subtype'設置被忽略. The filter must implement `inputImage', `inputTargetImage' and `inputTime' input keys, and the `outputImage' output key. Optionally it may support the `inputExtent' key, which will be set to a rectangle describing the region in which the transition should run. Defaults to nil. */
@property(nullable, strong) id filter;
TransitionType.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容