相關資源
GitHub粒子發(fā)射和復制圖層示例
GitHub粘性控件示例
GitHub彈性動畫
CALayer分析
響應者手勢分析
CAEmitter分析
QuartzCore 簡介
本文檔集合提供了核心動畫的API參考。核心動畫為應用程序提供動畫和顯示層次結構功能朝刊。有關詳細信息唐全,請參見 Core Animation Programming Guide。
QuartzCore主要結構
- CoreAnimation
- CADisplayLink定時器
- CALayer 及其子類(參考上方鏈接)
- CAMediaTiming協議相關
- CATransaction事物相關
- CATransform3D
可以看出所有的類和協議都以CA開頭,所以可以把此框架認為就是核心動畫框架
CoreAnimation簡介
核心動畫本身并不是繪圖系統。它是一個在硬件層面合成和操縱您的應用程序的內容的基礎設施。在此基礎設施的核心是CALayer對象犹菱,層用于管理和操作內容。一個圖層捕獲你的內容到一個位圖中吮炕,位圖可以很容易地被圖形硬件使用腊脱。在大多數應用中,層是用來管理View內容的龙亲,但也可以根據需要創(chuàng)建獨立獨立的層使用陕凹。
CoreAnimation基本使用思路
其實還有一個孫子類CASpringAnimation,它繼承自CABasicAnimation鳄炉,是用來做彈性動畫的杜耙。其實很多動畫UIKit中也有相關的API(包括彈性動畫),至于使用哪一種動畫:
- UIView動畫與核心動畫的區(qū)別?
- 核心動畫只作用在layer.
- 核心動畫修改的值都是假像.它的真實位置沒有發(fā)生變化拂盯,不會改變layer的frame泥技、transform屬性.
- 什么時候用UIView動畫什么時候用核心動畫?
- 當需要與用戶進行交互時用UIView,不需要與用戶進行交互時兩個都可以。
- 什么情況用核心動畫最多?
- 轉場動畫(UIView的轉場動畫類型比較少).
- 幀動畫.
- 動畫組.
CAAnimation使用
所有的核心動畫形式都定義在這個CAAnimation.h頭文件中
開發(fā)步驟:
- 首先得有CALayer(因為CoreAnimation是作用在CALayer上的
- 初始化一個CAAnimation對象磕仅,并設置一些動畫相關屬性
- 通過調用CALayer的addAnimation:forKey:方法珊豹,增加CAAnimation對象到CALayer中,這樣就能開始執(zhí)行動畫了
- 通過調用CALayer的removeAnimationForKey:方法可以停止CALayer中的動畫
CAMediaTiming協議
簡介:這個協議對于核心動畫很重要榕订。它提供對動畫節(jié)奏時間的控制的API店茶。 Layers and Animations都遵守并實現了協議方法。這個協議建立了分層的定時系統定時系統劫恒,每個對象描述的時間值都是映射自其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.
這個確實不好理解,不過我們可以通過測試總結:
- 他從動畫產生被添加到Layer上記錄一個時間a;
- 如果動畫是被beginTime 延遲了2秒吼虎,但是它的值是a+=2;
- 如果動畫被暫停了3(speed = 0),a還是會按系統時鐘走下去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數組中的每一個關鍵幀强胰。
@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;
/* 彈簧剛度系數联贩。必須大于0, Defaults to 100. */
@property CGFloat stiffness;
/* 阻尼系數捎拯, 必須大于或者等于0泪幌,Defaults to 10. */
@property CGFloat damping;
/* 附在彈簧上的物體的初速度,默認值0署照,代表沒有移動祸泪;負值表示網固定點反方向運動,正值反之 */
@property CGFloat initialVelocity;
/* 返回彈簧系統在靜止時所需的估計時間建芙。 時間是在當前系數下預估的浴滴。 */
@property(readonly) CFTimeInterval settlingDuration;
CAAnimationGroup
動畫組升略,動畫組,是CAAnimation的子類品嚣,可以保存一組動畫對象,將CAAnimationGroup對象加入層后翰撑,組中所有動畫對象可以同時并發(fā)運行啊央,屬性beginTime剛才也提到了,具有累加的效果瓜饥。
CATransition
轉場動畫,CATransition是CAAnimation的子類乓土,用于做轉場動畫溯警。UINavigationController就是通過CATransition實現了將控制器的視圖推入屏幕的動畫效果狡相。
/* 轉場動畫類型,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;