摘要: 動畫效果可以給用戶提供流暢的用戶體驗,在iOS系統(tǒng)中,Core Animation提供了一定的API來實現(xiàn)一些動畫效果。今天我們來學(xué)習(xí)下QuartzCore中 CAAnimation.h 類以及他的子類。
Apple官方提供CAAnimation繼承關(guān)系
先來介紹下蘋果提供的API,如下(通過這次也教大家如何查看Apple官方提供的 API)
- 通過開發(fā)工具 Xcode找到對應(yīng)的.h 文件
#import <QuartzCore/CALayer.h>
#import <Foundation/NSObject.h>
@class NSArray, NSString, CAMediaTimingFunction, CAValueFunction;
@protocol CAAnimationDelegate;
NS_ASSUME_NONNULL_BEGIN
/************************* 動畫基類 ***************************/
CA_CLASS_AVAILABLE (10.5, 2.0, 9.0, 2.0)
@interface CAAnimation : NSObject
<NSCoding, NSCopying, CAMediaTiming, CAAction>
{
@private
void *_attr;
uint32_t _flags;
}
/* 創(chuàng)建一個新的動畫對象*/
+ (instancetype)animation;
/* Animations implement the same property model as defined by CALayer. */
+ (nullable id)defaultValueForKey:(NSString *)key;
- (BOOL)shouldArchiveValueForKey:(NSString *)key;
/*
/** 時間函數(shù)名**/
CA_EXTERN NSString * const kCAMediaTimingFunctionLinear
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);//(線性):勻速,給你一個相對靜態(tài)的感覺
CA_EXTERN NSString * const kCAMediaTimingFunctionEaseIn
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);(漸進):動畫緩慢進入,然后加速離開
CA_EXTERN NSString * const kCAMediaTimingFunctionEaseOut
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);(漸出):動畫全速進入,然后減速的到達(dá)目的地
CA_EXTERN NSString * const kCAMediaTimingFunctionEaseInEaseOut
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);//(漸進漸出):動畫緩慢的進入,中間加速,然后減速的到達(dá)目的地。
CA_EXTERN NSString * const kCAMediaTimingFunctionDefault
CA_AVAILABLE_STARTING (10.6, 3.0, 9.0, 2.0);//默認(rèn),表示線性起搏
*/
@property(nullable, strong) CAMediaTimingFunction *timingFunction;
//動畫代理。設(shè)置之后在相應(yīng)時間會回調(diào)相應(yīng)的代理方法
@property(nullable, strong) id <CAAnimationDelegate> delegate;
//默認(rèn)為YES,代表動畫執(zhí)行完畢后就從圖層上移除,圖形會恢復(fù)到動畫執(zhí)行前的狀態(tài)。如果想讓圖層保持顯示動畫執(zhí)行后的狀態(tài),那就設(shè)置為NO,不過還要設(shè)置fillMode為kCAFillModeForwards .
@property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;
@end
/* CAAnimation delegate 方法。 */
@protocol CAAnimationDelegate <NSObject>
@optional
//動畫開始時的回調(diào)
- (void)animationDidStart:(CAAnimation *)anim;
//動畫停止的回調(diào),可以通過flag判斷動畫是否是完成還是暫停
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
@end
/********************* 屬性動畫類 ***************************/
CA_CLASS_AVAILABLE (10.5, 2.0, 9.0, 2.0)
@interface CAPropertyAnimation : CAAnimation
/* 創(chuàng)建一個新的動畫對象與其“keyPath”屬性設(shè)置為“道路”。 */
+ (instancetype)animationWithKeyPath:(nullable NSString *)path;
/* 動畫路徑 */
@property(nullable, copy) NSString *keyPath;
/* 默認(rèn) NO */
@property(getter=isAdditive) BOOL additive;
@property(getter=isCumulative) BOOL cumulative;
@property(nullable, strong) CAValueFunction *valueFunction;
@end
/**************** 提供對單一幀動畫的實現(xiàn) ****************/
CA_CLASS_AVAILABLE (10.5, 2.0, 9.0, 2.0)
@interface CABasicAnimation : CAPropertyAnimation
/*
fromValue:keyPath相應(yīng)屬性的初始值
toValue :keyPath相應(yīng)屬性的結(jié)束值(絶対値)
byValue :相對起始值的改變量
*/
@property(nullable, strong) id fromValue;
@property(nullable, strong) id toValue;
@property(nullable, strong) id byValue;
@end
/**************** 普通的幀動畫,可以定義動畫路線 ****************/
CA_CLASS_AVAILABLE (10.5, 2.0, 9.0, 2.0)
@interface CAKeyframeAnimation : CAPropertyAnimation
//里面的元素稱為“關(guān)鍵幀”(keyframe)。動畫對象會在指定的時間(duration)內(nèi),依次顯示values數(shù)組中的每一個關(guān)鍵幀。
@property(nullable, copy) NSArray *values;
//可以設(shè)置一個CGPathRef / CGMutablePathRef,讓層跟著路徑移動。path只對CALayer的anchorPoint和position起作用。如果你設(shè)置了path,那么values將被忽略。
@property(nullable) CGPathRef path;
//可以為對應(yīng)的關(guān)鍵幀指定對應(yīng)的時間點,其取值范圍為0到1.0,keyTimes中的每一個時間值都對應(yīng)values中的每一幀.當(dāng)keyTimes沒有設(shè)置的時候,各個關(guān)鍵幀對時間平均分配 .
@property(nullable, copy) NSArray<NSNumber *> *keyTimes;
/*
kCAMediaTimingFunctionLinear //線性
kCAMediaTimingFunctionEaseIn //淡入
kCAMediaTimingFunctionEaseOut //淡出
kCAMediaTimingFunctionEaseInEaseOut //淡入淡出
kCAMediaTimingFunctionDefault //默認(rèn)
*/
//這個屬性用以指定時間函數(shù),類似于運動的加速度,這是一個數(shù)組,你有幾個子路徑就應(yīng)該傳入幾個元素。
@property(nullable, copy) NSArray<CAMediaTimingFunction *> *timingFunctions;
/*
const kCAAnimationLinear //線性,默認(rèn)
const kCAAnimationDiscrete //離散,無中間過程,但keyTimes設(shè)置的時間依舊生效,物體跳躍地出現(xiàn)在各個關(guān)鍵幀上
const kCAAnimationPaced //平均,keyTimes跟timeFunctions失效
const kCAAnimationCubic //平均,同上
const kCAAnimationCubicPaced //平均,同上
*/
//該屬性決定了物體在每個子路徑下是跳著走還是勻速走。
@property(copy) NSString *calculationMode;
@property(nullable, copy) NSArray<NSNumber *> *tensionValues;
@property(nullable, copy) NSArray<NSNumber *> *continuityValues;
@property(nullable, copy) NSArray<NSNumber *> *biasValues;
/* `rotationMode' strings. */
CA_EXTERN NSString * const kCAAnimationRotateAuto
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);
CA_EXTERN NSString * const kCAAnimationRotateAutoReverse
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0);
@property(nullable, copy) NSString *rotationMode;
@end
/**************** 提供彈簧效果 (iOS9才引入的動畫類)****************/
CA_CLASS_AVAILABLE (10.11, 9.0, 9.0, 2.0)
@interface CASpringAnimation : CABasicAnimation
//質(zhì)量,影響圖層運動時的彈簧慣性,質(zhì)量越大,彈簧拉伸和壓縮的幅度越大。默認(rèn)為:1
@property CGFloat mass;
//彈簧剛度系數(shù)(勁度系數(shù)/彈性系數(shù)),剛度系數(shù)越大,形變產(chǎn)生的力就越大,運動越快。必須大于0.默認(rèn)值為100。
@property CGFloat stiffness;
//阻尼系數(shù),阻止彈簧伸縮的系數(shù),阻尼系數(shù)越大,停止越快。必須大于或等于0.默認(rèn)值為10。
@property CGFloat damping;
/*彈簧上的物體的初始速度。
默認(rèn)為0,表示一個不動的對象。
負(fù)值表示物體遠(yuǎn)離彈簧附接點,
正值表示物體朝向彈簧附接點移動。*/
@property CGFloat initialVelocity;
/*返回結(jié)算時間
彈簧動畫到停止時的估算時間,根據(jù)當(dāng)前的動畫參數(shù)估算*/
@property(readonly) CFTimeInterval settlingDuration;
@end
/************************* 提供漸變效果 ***************************/
CA_CLASS_AVAILABLE (10.5, 2.0, 9.0, 2.0)
@interface CATransition : CAAnimation
/* 過渡效果類型:(私有 API)
cube //立方體翻滾效果
oglFlip //上下左右翻轉(zhuǎn)效果
suckEffect //收縮效果,如一塊布被抽走(不支持過渡方向)
rippleEffect //滴水效果(不支持過渡方向)
pageCurl //向上翻頁效果
pageUnCurl //向下翻頁效果
cameraIrisHollowOpen //相機鏡
*/
/*
/* Common transition types. */
CA_EXTERN NSString * const kCATransitionFade
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0); //交叉淡化過渡(不支持過渡方向
CA_EXTERN NSString * const kCATransitionMoveIn
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0); //新視圖移到舊視圖上面
CA_EXTERN NSString * const kCATransitionPush
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0); //新視圖把舊視圖Push出去
CA_EXTERN NSString * const kCATransitionReveal
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0); //將舊視圖移開,顯示下面的新視圖
*/
//動畫過渡類型
@property(copy) NSString *type;
/ * 過渡方向
/* Common transition subtypes. */
CA_EXTERN NSString * const kCATransitionFromRight
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0); //右邊
CA_EXTERN NSString * const kCATransitionFromLeft
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0); //左邊
CA_EXTERN NSString * const kCATransitionFromTop
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0); //上邊
CA_EXTERN NSString * const kCATransitionFromBottom
CA_AVAILABLE_STARTING (10.5, 2.0, 9.0, 2.0); //下邊
* /
//動畫過渡方向
@property(nullable, copy) NSString *subtype;
//動畫起點(在整體動畫的百分比),值在[ 0,1 ]之間,默認(rèn)0
@property float startProgress;
//動畫終點(在整體動畫的百分比),值在[ 0,1 ]之間,默認(rèn)1
@property float endProgress;
//為動畫添加一個可選的濾鏡。
//如果指定,那么指定的filter必須同時支持x和y,否則該filter將不起作用。
//如果設(shè)置了filter,那么,為layer設(shè)置的type和subtype屬性將被忽略。
//如果設(shè)置了filter,那么必須實現(xiàn)`inputImage', `inputTargetImage' and `inputTime' input keys, and the `outputImage' output key. Optionally it may support the `inputExtent' key,
@property(nullable, strong) id filter;
@end
/****************** 允許多個動畫同時播放 ************************/
CA_CLASS_AVAILABLE (10.5, 2.0, 9.0, 2.0)
//CAAnimation的子類,可以保存一組動畫對象,將CAAnimationGroup對象加入層后,組中所有動畫對象可以同時并發(fā)運行
@interface CAAnimationGroup : CAAnimation
//用來存儲一組動畫對象
@property(nullable, copy) NSArray<CAAnimation *> *animations;
@end
NS_ASSUME_NONNULL_END
- 蘋果官方提供的 API 前面標(biāo)識符的意思如下:
1. C = Class 表示 類
2. M = Method 表示 方法
3. P = Property 表示 屬性
4. f =
使用例子
CAKeyframeAnimation
1、values
NSValue *value0 = [NSNumber numberWithFloat:1.0]; //第一幀
NSValue *value1 = [NSNumber numberWithFloat:1.1]; //第二幀
NSValue *value2 = [NSNumber numberWithFloat:1.0]; //第三幀
CAKeyframeAnimation *trAnimation =
[CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
trAnimation.values = @[value0, value1, value2];
trAnimation.duration = 0.6;
trAnimation.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[View.layer addAnimation:trAnimation forKey:nil];
2、path
CAKeyframeAnimation *animation =
[CAKeyframeAnimation animationWithKeyPath:@"position"];
animation.path = @"需要自己繪制路徑(CGMutablePathRef / CGPathRef)";
animation.removedOnCompletion = NO;
animation.autoreverses = NO;
animation.duration = 1.0;
animation.repeatCount = 0;
animation.fillMode = kCAFillModeForwards;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[view.layer addAnimation:animation forKey:@"animateLayer"];
CAAnimationGroup
CAAnimationGroup *animation = [CAAnimationGroup animation];
animation.animations = @[trAnimation,theAnimation];
animation.duration = 1.0;
animation.repeatCount = 0;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[view.layer addAnimation:animation forKey:@"animateLayer"];
CABasicAnimation
CABasicAnimation *theAnimation =
[CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
theAnimation.duration = 1;
theAnimation.repeatCount = 0;
theAnimation.removedOnCompletion = FALSE;
theAnimation.fillMode = kCAFillModeForwards;
theAnimation.autoreverses = YES;
theAnimation.fromValue = [NSNumber numberWithFloat:0];
theAnimation.toValue = [NSNumber numberWithFloat:-64];
[view.layer addAnimation:theAnimation forKey:@"animateLayer"];
UIView *bgView = [[UIView alloc] init];
bgView.bounds = CGRectMake(0, 0, 100,100);
bgView.center = self.view.center;
[self.view addSubview:bgView];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.frame = CGRectMake(0, 0, 100, 100);
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:bgView.bounds];
shapeLayer.path = path.CGPath;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.lineWidth = 2.0f;
shapeLayer.strokeColor = [UIColor redColor].CGColor;
[bgView.layer addSublayer:shapeLayer];
//@property CGFloat strokeStart;
//@property CGFloat strokeEnd;
CABasicAnimation *pathAnima = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnima.duration = 3.0f;
pathAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pathAnima.fromValue = [NSNumber numberWithFloat:0.0f];
pathAnima.toValue = [NSNumber numberWithFloat:1.0f];
pathAnima.fillMode = kCAFillModeForwards;
pathAnima.removedOnCompletion = NO;
[shapeLayer addAnimation:pathAnima forKey:@"strokeEndAnimation"];
如果animationWithKeyPath:方法創(chuàng)建對象,參數(shù)如下:
| Structure Field | Description |
|---|---|
| rotation.x | The rotation, in radians, in the x axis. |
| rotation.y | The rotation, in radians, in the y axis. |
| rotation.x | The rotation, in radians, in the z axis. |
| rotation | The rotation, in radians, in the z axis. This is identical to setting the rotation.z field. |
| scale.x | Scale factor for the x axis. |
| scale.y | Scale factor for the y axis. |
| scale.x | Scale factor for the z axis. |
| scale | Average of all three scale factors. |
| translation.x | Translate in the x axis. |
| translation.y | Translate in the y axis. |
| translation.x | Translate in the z axis. |
| translation | Translate in the x and y axis. Value is an NSSize or CGSize. |
CASpringAnimation
。。。
CAPropertyAnimation
。。。
CATransition
CATransition *trAnimation = [CATransition animation];
trAnimation.duration = 1.0;
trAnimation.type = kCATransitionPush;
trAnimation.subtype = kCATransitionFromTop;
trAnimation.startProgress = 0.0;
trAnimation.endProgress = 1.0;
trAnimation.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[View.layer addAnimation:trAnimation forKey:@"transition"];
trAnimation.type 蘋果公開的類型僅僅有四種類型分別是:
淡化、推擠、揭開、覆蓋
NSString * const kCATransitionFade;
NSString * const kCATransitionMoveIn;
NSString * const kCATransitionPush;
NSString * const kCATransitionReveal;
trAnimation.subtype 蘋果提供的類型有如下四種:
從右側(cè)、從左側(cè)、從頂部、從底部
NSString * const kCATransitionFromRight;
NSString * const kCATransitionFromLeft;
NSString * const kCATransitionFromTop;
NSString * const kCATransitionFromBottom;
對于trAnimation.type類型蘋果還提供了一定的私有API分別如下:
立方體、吸收、翻轉(zhuǎn)、波紋、翻頁、反翻頁、鏡頭開、鏡頭關(guān)
animation.type = @"cube"
animation.type = @"suckEffect";
animation.type = @"oglFlip";
animation.type = @"rippleEffect";
animation.type = @"pageCurl";
animation.type = @"pageUnCurl"
animation.type = @"cameraIrisHollowOpen";
animation.type = @"cameraIrisHollowClose";
- CATransition 的 startProgress 和 endProgress屬性介紹:
可以控制動畫進行的過程,可以讓動畫停留在某個動畫點上,值在0.0到1.0之間。endProgress要大于等于startProgress。比如上面的立方體轉(zhuǎn)到,可以設(shè)置endProgress= 0.5,讓動畫停留在轉(zhuǎn)動一般的位置。
