一些很有用的參考泰偿,基本的講解都可以在這里找到
系統(tǒng)的學(xué)習(xí)CoreAnimation可以看一下這本書(shū)
https://legacy.gitbook.com/book/zsisme/ios-/details
這本書(shū)的示例代碼(本文不再寫(xiě)示例避凝,大部分的示例可以在這里找到)
https://github.com/pflnh/CoreAnimationCode
還有蘋(píng)果官方的guide
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40004514-CH1-SW1
CoreAnimation中的類結(jié)構(gòu)
CAAnimation主要分為:轉(zhuǎn)場(chǎng)動(dòng)畫(huà)(CATransition)、關(guān)鍵幀動(dòng)畫(huà)(CAKeyframeAnimation)挪凑、基本動(dòng)畫(huà)(CABasicAnimation)批销、組合動(dòng)畫(huà)(CAAnimationGroup)戈次。
CAMediaTiming協(xié)議
@protocol CAMediaTiming
//對(duì)象的開(kāi)始時(shí)間耸彪,指動(dòng)畫(huà)開(kāi)始之前的的時(shí)間。默認(rèn)是0.
@property CFTimeInterval beginTime;
//對(duì)象的持續(xù)時(shí)間栈雳,默認(rèn)是0.
@property CFTimeInterval duration;
//圖層的比率护奈,用來(lái)衡量最初時(shí)間和當(dāng)前時(shí)間。例如:如果比率為2哥纫,當(dāng)前花費(fèi)的時(shí)間就是最初時(shí)間的0.5霉旗。默認(rèn)是1。
@property float speed;
/*時(shí)間軸偏移量磺箕。將時(shí)間軸移動(dòng)至偏移位置奖慌,再執(zhí)行整個(gè)動(dòng)畫(huà)時(shí)長(zhǎng)。假設(shè)動(dòng)畫(huà)時(shí)長(zhǎng)5秒松靡,偏移量為13,
則開(kāi)始位置為13 % 5 = 3建椰,再執(zhí)行一次動(dòng)畫(huà)時(shí)長(zhǎng)5秒雕欺,即在時(shí)長(zhǎng)位置3處結(jié)束。*/
@property CFTimeInterval timeOffset;
//重復(fù)次數(shù)
@property float repeatCount;
//對(duì)象的重復(fù)持續(xù)時(shí)間棉姐。默認(rèn)是0屠列。
@property CFTimeInterval repeatDuration;
//是否自動(dòng)換向。如果為YES伞矩,那么動(dòng)畫(huà)執(zhí)行完會(huì)按照原來(lái)的路徑返回笛洛。默認(rèn)是NO。
@property BOOL autoreverses;
/*決定當(dāng)前對(duì)象過(guò)了非active時(shí)間段的行為. 比如動(dòng)畫(huà)開(kāi)始之前乃坤、動(dòng)畫(huà)結(jié)束之后苛让。
如果是CAAnimationd對(duì)象,則需要將其removedOnCompletion設(shè)置為NO,要不然fillMode不起作用
*/
@property(copy) NSString *fillMode;
@end
??fillMode的各種可選值:
kCAFillModeRemoved 默認(rèn)值沟蔑。動(dòng)畫(huà)開(kāi)始前和動(dòng)畫(huà)結(jié)束后,動(dòng)畫(huà)對(duì)layer都沒(méi)有影響,動(dòng)畫(huà)結(jié)束后,layer會(huì)恢復(fù)到之前的狀態(tài)
kCAFillModeForwards 動(dòng)畫(huà)結(jié)束后,layer會(huì)一直保持著動(dòng)畫(huà)最后的狀態(tài)
kCAFillModeBackwards 動(dòng)畫(huà)開(kāi)始前,只要將動(dòng)畫(huà)加入了一個(gè)layer,layer便立即進(jìn)入動(dòng)畫(huà)的初始狀態(tài)并等待動(dòng)畫(huà)開(kāi)始
kCAFillModeBoth 動(dòng)畫(huà)開(kāi)始之前,layer處于動(dòng)畫(huà)初始狀態(tài),動(dòng)畫(huà)結(jié)束后layer保持動(dòng)畫(huà)最后的狀態(tài)
1、轉(zhuǎn)場(chǎng)動(dòng)畫(huà)(CATransition)
@interface CATransition : CAAnimation
/* 過(guò)渡動(dòng)畫(huà)名狱杰。當(dāng)前合法的動(dòng)畫(huà)類型有:`fade', `moveIn', `push' and `reveal'. 默認(rèn)是`fade'. */
@property(copy) NSString *type;
/* 一個(gè)可選擇的動(dòng)畫(huà)子類型. 用來(lái)指定動(dòng)畫(huà)的運(yùn)動(dòng)方向瘦材,合法的值是: `fromLeft', `fromRight', `fromTop' and * `fromBottom'. */
@property(nullable, copy) NSString *subtype;
/* 這兩個(gè)屬性用來(lái)控制過(guò)渡動(dòng)畫(huà)的開(kāi)始、結(jié)束執(zhí)行過(guò)程仿畸,可以讓動(dòng)畫(huà)停留在某個(gè)動(dòng)畫(huà)點(diǎn)上食棕。合法的值是在0~1范圍內(nèi)。endProgress必須比startProgress的值要大错沽。默認(rèn)值是0—1.
*/
@property float startProgress;
@property float endProgress;
/*filter對(duì)象用來(lái)實(shí)現(xiàn)過(guò)渡動(dòng)畫(huà)簿晓。如果設(shè)置了filter,那么為layer設(shè)置的type和subtype屬性將被忽略千埃。*/
@property(nullable, strong) id filter;
@end
2抢蚀、基本動(dòng)畫(huà)(CABasicAnimation)
CAPropertyAnimation是通過(guò)animationWithKeyPath方法來(lái)進(jìn)行實(shí)例化的,所以CABasicAnimation镰禾、CAKeyframeAnimation都可以通過(guò)animationWithKeyPath的值來(lái)設(shè)定動(dòng)畫(huà)樣式皿曲。
@interface CABasicAnimation : CAPropertyAnimation
@property(nullable, strong) id fromValue;//所改變屬性的起始值
@property(nullable, strong) id toValue;//所改變屬性的結(jié)束時(shí)的值
@property(nullable, strong) id byValue;//所改變屬性相同起始值的改變量
@end
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"XXX"];
其中的keyPath可以在蘋(píng)果的官方文檔中找到所有的可選值。
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/AnimatableProperties/AnimatableProperties.html#//apple_ref/doc/uid/TP40004514-CH11-SW1
3吴侦、關(guān)鍵幀動(dòng)畫(huà)(CAKeyframeAnimation)
@interface CAKeyframeAnimation : CAPropertyAnimation
/*存儲(chǔ)關(guān)鍵幀(keyframe)元素屋休。動(dòng)畫(huà)對(duì)象會(huì)在指定的時(shí)間(duration)內(nèi),依次顯示values數(shù)組中的每一個(gè)關(guān)鍵幀备韧。*/
@property(nullable, copy) NSArray *values;
/*設(shè)置CGPathRef\CGMutablePathRef,讓layer跟著設(shè)定的路徑移動(dòng)劫樟。path只對(duì)CALayer的anchorPoint和position起作用。如果設(shè)置了path织堂,values將被忽略叠艳。*/
@property(nullable) CGPathRef path;
/*為對(duì)應(yīng)的關(guān)鍵幀指定對(duì)應(yīng)的時(shí)間點(diǎn),其取值范圍為0到1.0,keyTimes中的每一個(gè)時(shí)間值都對(duì)應(yīng)values中的每一幀.當(dāng)keyTimes沒(méi)有設(shè)置的時(shí)候,各個(gè)關(guān)鍵幀的時(shí)間是平均分配的。*/
@property(nullable, copy) NSArray<NSNumber *> *keyTimes;
/*速度控制函數(shù),有kCAMediaTimingFunctionLinear易阳、kCAMediaTimingFunctionEaseIn附较、kCAMediaTimingFunctionEaseOut、kCAMediaTimingFunctionEaseInEaseOut四種方式潦俺,默認(rèn)是最后一種*/
@property(nullable, copy) NSArray<CAMediaTimingFunction *> *timingFunctions
/*計(jì)算模式拒课。主要針對(duì)的是每一幀的內(nèi)容為一個(gè)座標(biāo)點(diǎn)的情況,也就是對(duì)anchorPoint 和 position 進(jìn)行的動(dòng)畫(huà)。
目前提供如下幾種模式:kCAAnimationLinear事示、kCAAnimationDiscrete 早像、kCAAnimationPaced
、kCAAnimationCubic 肖爵、kCAAnimationCubicPaced卢鹦。*/
@property(copy) NSString *calculationMode;
/* 該值控制著曲線的緊密度(正值將越緊,負(fù)值將越寬松)*/
@property(nullable, copy) NSArray<NSNumber *> *tensionValues;
/*該值控制片段之間的鏈接(正值將有鋒利的圓角劝堪,負(fù)值將是倒立的圓角)*/
@property(nullable, copy) NSArray<NSNumber *> *continuityValues;
/*該值定義了曲線發(fā)生的地點(diǎn)(正值將在控制點(diǎn)前移動(dòng)曲線冀自,負(fù)值將在控制點(diǎn)后移動(dòng))*/
@property(nullable, copy) NSArray<NSNumber *> *biasValues;
/*定義是否沿著路徑旋轉(zhuǎn)匹配對(duì)象動(dòng)畫(huà)路徑切線揉稚,值可能為kCAAnimationRotateAuto和kCAAnimationRotateAutoReverse。默認(rèn)是nil凡纳。如果沒(méi)有路徑對(duì)象窃植,設(shè)置該屬性值將無(wú)效,kCAAnimationRotateAutoReverse為了匹配正切將添加180°荐糜。*/
@property(nullable, copy) NSString *rotationMode;
@end
4巷怜、組合動(dòng)畫(huà)(CAAnimationGroup)
@interface CAAnimationGroup : CAAnimation
/* 存儲(chǔ)CAAnimation對(duì)象的數(shù)組。數(shù)組的每一個(gè)元素在規(guī)定的duration時(shí)間內(nèi)同時(shí)進(jìn)行暴氏。*/
@property(nullable, copy) NSArray<CAAnimation *> *animations;
@end
tips:在動(dòng)畫(huà)執(zhí)行過(guò)程中延塑,一般如果不加入任何設(shè)置動(dòng)畫(huà)會(huì)還原,可以使用以下方式來(lái)關(guān)閉這種效果答渔。
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[CATransaction begin];
[CATransaction setDisableActions:YES];
[CATransaction commit];
UIView動(dòng)畫(huà)
1关带、UIViewAnimation
@interface UIView(UIViewAnimation)
//開(kāi)始動(dòng)畫(huà)。傳遞的context值會(huì)傳遞給代理的start/did stop方法中沼撕。
+ (void)beginAnimations:(nullable NSString *)animationID context:(nullable void *)context;
//和beginAnimations方法成對(duì)出現(xiàn)宋雏。代表動(dòng)畫(huà)開(kāi)始和執(zhí)行,動(dòng)畫(huà)內(nèi)容放在兩個(gè)個(gè)方法中間务豺。
+ (void)commitAnimations;
// 設(shè)置動(dòng)畫(huà)代理磨总,當(dāng)動(dòng)畫(huà)開(kāi)始或者結(jié)束時(shí)會(huì)發(fā)消息給代理對(duì)象。默認(rèn)是nil笼沥。
+ (void)setAnimationDelegate:(nullable id)delegate;
//動(dòng)畫(huà)即將開(kāi)始時(shí)蚪燕,執(zhí)行selector,并且把beginAnimations:context:中傳入的參數(shù)傳進(jìn)selector
+ (void)setAnimationWillStartSelector:(nullable SEL)selector;
//動(dòng)畫(huà)即將結(jié)束時(shí)奔浅,執(zhí)行selector馆纳,并且把beginAnimations:context:中傳入的參數(shù)傳進(jìn)selector
+ (void)setAnimationDidStopSelector:(nullable SEL)selector;
//動(dòng)畫(huà)的持續(xù)時(shí)間,以秒為單位汹桦。默認(rèn)是0.2.
+ (void)setAnimationDuration:(NSTimeInterval)duration;
//動(dòng)畫(huà)延遲鲁驶。默認(rèn)是0。
+ (void)setAnimationDelay:(NSTimeInterval)delay;
//默認(rèn)是now.
+ (void)setAnimationStartDate:(NSDate *)startDate;
//動(dòng)畫(huà)的節(jié)奏控制营勤。默認(rèn)是UIViewAnimationCurveEaseInOut灵嫌。
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve;
//動(dòng)畫(huà)重復(fù)次數(shù)。默認(rèn)是0.
+ (void)setAnimationRepeatCount:(float)repeatCount;
//動(dòng)畫(huà)是否逆向運(yùn)行葛作。如果是YES的話,動(dòng)畫(huà)會(huì)按照原來(lái)的運(yùn)動(dòng)軌跡逆向返回猖凛。默認(rèn)是NO赂蠢。
+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses;
//動(dòng)畫(huà)是否從當(dāng)前狀態(tài)開(kāi)始。默認(rèn)是NO辨泳。如果為YES虱岂,那么動(dòng)畫(huà)在運(yùn)行過(guò)程中當(dāng)前視圖的位置將會(huì)作為新的動(dòng)畫(huà)的開(kāi)始狀態(tài)玖院。如果設(shè)置為NO,新動(dòng)畫(huà)將使用視圖最後狀態(tài)的位置作為開(kāi)始狀態(tài)第岖。
+ (void)setAnimationBeginsFromCurrentState:(BOOL)fromCurrentState;
//設(shè)置view的過(guò)渡效果, transition是設(shè)定過(guò)渡類型, cache為YES時(shí)代表使用視圖緩存难菌。
+ (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache;
//是否激活動(dòng)畫(huà)。如果是YES蔑滓,就激活動(dòng)畫(huà)郊酒,當(dāng)動(dòng)畫(huà)參數(shù)沒(méi)有被激活那么動(dòng)畫(huà)屬性的改變將被忽略。默認(rèn)是YES键袱。
+ (void)setAnimationsEnabled:(BOOL)enabled;
#if UIKIT_DEFINE_AS_PROPERTIES
@property(class, nonatomic, readonly) BOOL areAnimationsEnabled;
#else
+ (BOOL)areAnimationsEnabled;
#endif
+ (void)performWithoutAnimation:(void (NS_NOESCAPE ^)(void))actionsWithoutAnimation NS_AVAILABLE_IOS(7_0);
#if UIKIT_DEFINE_AS_PROPERTIES
@property(class, nonatomic, readonly) NSTimeInterval inheritedAnimationDuration NS_AVAILABLE_IOS(9_0);
#else
+ (NSTimeInterval)inheritedAnimationDuration NS_AVAILABLE_IOS(9_0);
#endif
@end
2燎窘、UIViewAnimationWithBlocks
@interface UIView(UIViewAnimationWithBlocks)
/**
block動(dòng)畫(huà),可以設(shè)置動(dòng)畫(huà)時(shí)長(zhǎng)蹄咖、動(dòng)畫(huà)延遲褐健、動(dòng)畫(huà)選項(xiàng)、動(dòng)畫(huà)結(jié)束狀態(tài)澜汤、動(dòng)畫(huà)完成后最終狀態(tài)蚜迅,
可根據(jù)自己實(shí)際需要選擇下面3種實(shí)現(xiàn)方式
**/
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0); // delay = 0.0, options = 0
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations NS_AVAILABLE_IOS(4_0); // delay = 0.0, options = 0, completion = NULL
//視圖過(guò)渡動(dòng)畫(huà)
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);
//視圖間過(guò)渡動(dòng)畫(huà)
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0); // toView added to fromView.superview, fromView removed from its superview
//彈簧動(dòng)畫(huà)
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
//刪除視圖動(dòng)畫(huà)
+ (void)performSystemAnimation:(UISystemAnimation)animation onViews:(NSArray<__kindof UIView *> *)views options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))parallelAnimations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
@end
3、UIViewKeyframeAnimations
@interface UIView (UIViewKeyframeAnimations)
//設(shè)定動(dòng)畫(huà)時(shí)長(zhǎng)俊抵、動(dòng)畫(huà)延遲谁不、關(guān)鍵幀選項(xiàng)、關(guān)鍵幀
+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
//添加關(guān)鍵幀動(dòng)畫(huà)的開(kāi)始時(shí)間务蝠、幀動(dòng)畫(huà)在整個(gè)動(dòng)畫(huà)的比例
+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations NS_AVAILABLE_IOS(7_0); // start time and duration are values between 0.0 and 1.0 specifying time and duration relative to the overall time of the keyframe animation
@end
UIView動(dòng)畫(huà)和CoreAnimation的關(guān)系
我們可以看以下這兩篇文章
http://www.reibang.com/p/72f4cca98b0e
http://www.reibang.com/p/9e9c8ee3f7a2
UIVIew動(dòng)畫(huà)通過(guò)view.layer的action對(duì)象的actionForLayer:forKey:
來(lái)實(shí)現(xiàn)動(dòng)畫(huà)的拍谐。UIView動(dòng)畫(huà)就是對(duì)CoreAnimation動(dòng)畫(huà)的一種封裝。同時(shí)我們也可以使用自定義的aciton對(duì)象來(lái)改變一些默認(rèn)的隱式動(dòng)畫(huà)效果馏段。