經過前幾篇博客的介紹,咱們能夠了解到layer層能夠設置許多與控件UI相關的屬性,而且對於iOS開發,UIView層的屬性是會映射到CALayer的,所以,能夠經過UIKit和CoreAnimation兩個框架來設置控件的UI相關屬性,當屬性發生變化時,咱們能夠使其展現一個動畫效果。數組
CAAnimation是CoreAnimation框架中執行動畫對象的基類,下面有一張圖,是我手畫的,不太美觀,可是能夠將與CAAnimation相關的幾個動畫類的關係表達清楚:框架
從上圖中能夠看到,從CAAnimation中繼承出三個子類,分別是用於建立屬性動畫的CAPropertyAnimation,建立轉場動畫的CATransition和建立組合動畫的CAAnimationGroup。動畫
咱們就先從根類開始探討。url
CAAnimation做爲動畫對象的基類,其中封裝了動畫的基礎屬性,以下:spa
//經過類方法建立一個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的代理方法入以下幾個:code
//動畫開始時執行的回調 - (void)animationDidStart:(CAAnimation *)anim; //動畫結束後執行的回調 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
CAPropertyAnimation是繼承於CAAnimation專門用來建立與屬性相關的動畫的類:orm
//建立對象 參數中的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:@""];
CABasicAnimaton是CAPropertyAnimation分出來的一個子類,建立基礎的屬性變化動畫,例如咱們上面的示例代碼,其中屬性以下:
@property(nullable, strong) id fromValue; @property(nullable, strong) id toValue; @property(nullable, strong) id byValue;
上面三個屬性都是來肯定動畫的起始與結束位置,有以下的含義:
fromValue和toValue不爲空:動畫的值由fromValue變化到toValue
fromValue和byValue不爲空:動畫的值由fromValue變化到fromValue+byValue
byValue和toValue不爲空:動畫的值由toValue-byValue變化到toValue
只有fromValue不爲空:動畫的值由fromValue變化到layer的當前狀態值
只有toValue不爲空:動畫的值由layer當前的值變化到toValue
只有byValue不爲空:動畫的值由layer當前的值變化到layer當前的值+byValue
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:@""];
經過CASpringAnimation,能夠幫助開發者很輕鬆的建立出有彈簧效果的動畫,主要屬性以下:
//這個屬性設置彈簧重物的質量 會影響慣性 必須大於0 默認爲1 @property CGFloat mass; //設置彈簧的剛度係數,必須大於0 默認爲100 這個越大 則回彈越快 @property CGFloat stiffness; //阻尼係數 默認爲10 必須大於0 這個值越大 回彈的幅度越小 @property CGFloat damping; //初始速度 @property CGFloat initialVelocity; //獲取動畫停下來須要的時間 @property(readonly) CFTimeInterval settlingDuration;
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定義的動畫效果,出來官方定義的,咱們還能夠使用一些私有的參數,以下:
pageCurl 翻頁 rippleEffect 滴水效果 suckEffect 收縮效果,如一塊布被抽走 cube 立方體效果 oglFlip 上下翻轉效果
例如:
CATransition * ani = [CATransition animation]; ani.type = @"pageCurl"; ani.subtype = kCATransitionFromRight; [layer addAnimation:ani forKey:@""];
CAAnimationGroup自己並無定義動畫,他能夠將咱們上面提到的相關動畫進行組合:
@property(nullable, copy) NSArray<CAAnimation *> *animations;
專一技術,熱愛生活,交流技術,也作朋友。
——琿少 QQ羣:203317592