CAAnimation動畫體系的介紹
CAAnimation是CoreAnimation架構中執行動畫對象的基類,下面有一張圖,是我手畫的,不太美觀,但是可以將與CAAnimation相關的幾個動畫類的關係表達清楚:
從上圖中可以看到,從CAAnimation中繼承出三個子類,分別是用於建立屬性動畫的CAPropertyAnimation,建立轉場動畫的CATransition和建立組合動畫的CAAnimationGroup。
我們就先從根類開始探討。
1.CAAnimation屬性和方法
CAAnimation作為動畫對象的基類,其中封裝了動畫的基礎屬性,如下:
//通過類方法建立一個CAAnimation對象
+ (instancetype)animation;
//動畫執行的時序模式
@property(nullable, strong) CAMediaTimingFunction *timingFunction;
//代理
@property(nullable, strong) id delegate;
//是否動畫完成時將動畫對象移除掉
@property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;
timingFunction定義了動畫執行的時序效果,CAMediaTimingFunction的建立方式如下:
/*
name參數決定的執行的效果,選擇性參數如下
//線性執行
NSString * const kCAMediaTimingFunctionLinear;
//淡入 在動畫開始時 淡入效果
NSString * const kCAMediaTimingFunctionEaseIn;
//淡出 在動畫結束時 淡出效果
NSString * const kCAMediaTimingFunctionEaseOut;
//淡入淡出
NSString * const kCAMediaTimingFunctionEaseInEaseOut;
//預設效果
NSString * const kCAMediaTimingFunctionDefault;
*/
+ (instancetype)functionWithName:(NSString *)name;
CAAnimation的代理方法入如下幾個:
//動畫開始時執行的回調
- (void)animationDidStart:(CAAnimation *)anim;
//動畫結束後執行的回調
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
2.CAPropertyAnimation屬性與方法
CAPropertyAnimation是繼承於CAAnimation專門用來建立與屬性相關的動畫的類:
//建立對象 參數中的path就是我們要執行動畫的屬性
//例如,如果傳入@"backgroundColor" 當layer的背景顏色改變時,就會執行我們設定的動畫
+ (instancetype)animationWithKeyPath:(nullable NSString *)path;
//這個屬性確定動畫執行的狀態是否疊加在控制項的原狀態上
//預設設定為NO,如果我們執行兩次位置移動的動畫,會從同一位置執行兩次
//如果設定為YES,則會在第一次執行的基礎上執行第二次動畫
@property(getter=isAdditive) BOOL additive;
//這個屬性對重複執行的動畫有效果
//預設為NO,重複執行的動畫每次都是從起始狀態開始
//如果設定為yes,則為此執行都會在上一次執行的基礎上執行
@property(getter=isCumulative) BOOL cumulative;
//這個屬性和transfron屬性的動畫執行相關
@property(nullable, strong) CAValueFunction *valueFunction;
上面這些屬性中,只有一個需要我們注意,valueFunction是專門為了transform動畫而設定的,因為我們沒有辦法直接改變transform3D中的屬性,通過這個參數,可以協助我們直接操作transfrom3D屬性變化產生動畫效果,舉例如下,一個繞Z軸旋轉的動畫:
//繞z軸旋轉的動畫
CABasicAnimation * ani = [CABasicAnimation animationWithKeyPath:@"transform"];
//從0度開始
ani.fromValue = @0;
//旋轉到180度
ani.toValue = [NSNumber numberWithFloat:M_PI];
//時間2S
ani.duration = 2;
//設定為z軸旋轉
ani.valueFunction = [CAValueFunction functionWithName:kCAValueFunctionRotateZ];
//執行動畫
[layer addAnimation:ani forKey:@""];
實際上,使用點的方式也是可以訪問到相應屬性的,如果不設定valueFunction,使用如下方法也是可以進行繞Z軸旋轉的:
//繞z軸旋轉的動畫
CABasicAnimation * ani = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
//從0度開始
ani.fromValue = @0;
//旋轉到180度
ani.toValue = [NSNumber numberWithFloat:M_PI];
//時間2S
ani.duration = 2;
//執行動畫
[layer addAnimation:ani forKey:@""];
3.CABasicAnimation屬性
CABasicAnimaton是CAPropertyAnimation分出來的一個子類,建立基礎的屬性變化動畫,例如我們上面的範例程式碼,其中屬性如下:
@property(nullable, strong) id fromValue;
@property(nullable, strong) id toValue;
@property(nullable, strong) id byValue;
上面三個屬性都是來確定動畫的起始與結束位置,有如下的含義:
(1)fromValue和toValue不為空白:動畫的值由fromValue變化到toValue
(2)fromValue和byValue不為空白:動畫的值由fromValue變化到fromValue+byValue
(3)byValue和toValue不為空白:動畫的值由toValue-byValue變化到toValue
(4)只有fromValue不為空白:動畫的值由fromValue變化到layer的目前狀態值
(5)只有toValue不為空白:動畫的值由layer當前的值變化到toValue
(6)只有byValue不為空白:動畫的值由layer當前的值變化到layer當前的值+byValue
4.CAKeyframeAnimation主要畫面格動畫
CAKeyframeAnimation也是繼承與CAPropertyAnimation的一個子類,其與CABasicAnimation的不同之處在於雖然其都是改變layer層屬性的動畫,但是CABasicAnimation只能設定初始與結束狀態,這之間我們沒辦法控制,而CAKeyframeAnimation可以讓我們設定一些主要畫面格再整個動畫的過程中。屬性方法如下:
//主要畫面格的值數組 例如我們想讓控制項沿某個路徑移動,這裡面存放每個移動的點
@property(nullable, copy) NSArray *values;
//直接設定路徑,範圍values類似
@property(nullable) CGPathRef path;
//設定每一幀執行的時間長短 這個的取值為0-1,代表佔用時間的比例
@property(nullable, copy) NSArray<NSNumber *> *keyTimes;
//每一幀執行過程中的時序效果 上面有提過
@property(nullable, copy) NSArray<CAMediaTimingFunction *> *timingFunctions;
/*
設定幀的中間值如何計算
NSString * const kCAAnimationLinear;
NSString * const kCAAnimationDiscrete;
NSString * const kCAAnimationPaced;
NSString * const kCAAnimationCubic;
NSString * const kCAAnimationCubicPaced;
*/
@property(copy) NSString *calculationMode;
樣本如下:
CAKeyframeAnimation * ani = [CAKeyframeAnimation animationWithKeyPath:@"position"];
ani.values = @[[NSValue valueWithCGPoint:CGPointMake(100, 100)],[NSValue valueWithCGPoint:CGPointMake(120, 100)],[NSValue valueWithCGPoint:CGPointMake(120, 200)],[NSValue valueWithCGPoint:CGPointMake(200, 200)]];
ani.duration = 3;
[layer addAnimation:ani forKey:@""];
5.CASpringAnimation阻尼動畫
通過CASpringAnimation,可以協助開發人員很輕鬆的建立出有彈簧效果的動畫,主要屬性如下:
//這個屬性設定彈簧重物的品質 會影響慣性 必須大於0 預設為1
@property CGFloat mass;
//設定彈簧的剛度係數,必須大於0 預設為100 這個越大 則回彈越快
@property CGFloat stiffness;
//阻尼係數 預設為10 必須大於0 這個值越大 回彈的幅度越小
@property CGFloat damping;
//初始速度
@property CGFloat initialVelocity;
//擷取動畫停下來需要的時間
@property(readonly) CFTimeInterval settlingDuration;
6.CATransition轉場動畫
CATransition和CAPropertyAnimation的不同之處在於當layer層出現時,會產生動畫效果,而並不是屬性改變時,屬性如下:
/*
設定動畫類型
//淡入
NSString * const kCATransitionFade;
//移入
NSString * const kCATransitionMoveIn;
//壓入
NSString * const kCATransitionPush;
//溶解
NSString * const kCATransitionReveal;
*/
@property(copy) NSString *type;
/*
設定動畫的方向
//從右側進
NSString * const kCATransitionFromRight;
//從左側進
NSString * const kCATransitionFromLeft;
//從上側進
NSString * const kCATransitionFromTop;
//從下側進
NSString * const kCATransitionFromBottom;
*/
@property(nullable, copy) NSString *subtype;
其實,關於type定義的動畫效果,出來官方定義的,我們還可以使用一些私人的參數,如下:
(1)pageCurl 翻頁
(2)rippleEffect 滴水效果
(3)suckEffect 收縮效果,如一塊布被抽走
(4)cube 立方體效果
(5)oglFlip 上下翻轉效果
例如:
CATransition * ani = [CATransition animation];
ani.type = @"pageCurl";
ani.subtype = kCATransitionFromRight;
[layer addAnimation:ani forKey:@""];
7.CAAnimationGroup動畫組
CAAnimationGroup本身並沒有定義動畫,他可以將我們上面提到的相關動畫進行組合:
@property(nullable, copy) NSArray<CAAnimation *> *animations;
進階動畫技巧
1.事務類
CoreAnimation中還有一個非常重要的類:CATransaction事物類,這個可以同時設定多個layer層的動畫效果。可以通過隱式和顯式兩種方式來進行動畫操作。
2.CATransaction屬性
對layer層的屬性操作,都會形成隱式動畫,要使用隱式動畫,需要關閉layer層的animation動畫屬性,使用下面的方法:
//關閉animation動畫效果,開啟隱式動畫
+ (BOOL)disableActions;
+ (void)setDisableActions:(BOOL)flag;
CATransaction用類方式通過設定key-value來進行動畫的屬性設定:
+ (nullable id)valueForKey:(NSString *)key;
+ (void)setValue:(nullable id)anObject forKey:(NSString *)key;
支援的key值如下:
//設定動畫期間
NSString * const kCATransactionAnimationDuration;
//設定停用animation類動畫
NSString * const kCATransactionDisableActions;
//設定動畫時序效果
NSString * const kCATransactionAnimationTimingFunction;
//設定動畫完成後的回調
NSString * const kCATransactionCompletionBlock;
除了隱式的展示動畫外,也可以顯式的通過調用CATransaction的相關方法進行顯示的提交動畫:
//動畫開始
+ (void)begin;
//提交動畫
+ (void)commit;
//立即進行動畫渲染 一般不需調用
+ (void)flush;
//下面這兩個方法用於動畫事物的加鎖與解鎖 在多線程動畫中,保證修改屬性的安全
+ (void)lock;
+ (void)unlock;
樣本如下:
[CATransaction begin];
[CATransaction setValue:@1 forKey:kCATransactionAnimationDuration];
layer.backgroundColor = [UIColor blueColor].CGColor;
[CATransaction commit];