Core Animation 實際是直接作用在 CALayer 上的,而不是UIView上倔既。view是負(fù)責(zé)響應(yīng)事件的,layer是負(fù)責(zé)顯示的,可以看成view是layer的包裝類鹏氧。同時Core Animation 的動畫執(zhí)行過程都是在后臺操作的渤涌,不會阻塞主線程。
? CAAnimation是所有動畫對象的父類把还,負(fù)責(zé)控制動畫的持續(xù)時間和速度,是個 抽象類 ---- 即实蓬,不能直接使用茸俭,應(yīng)該使用其具體子類。需要注意的是CAAnimation 和 CAPropertyAnimation 都是 抽象類安皱。
首先调鬓,我們先看一下繼承結(jié)構(gòu)圖:
CAAnimation(動畫基類)
CAAnimation主要包含三個屬性,兩個代理方法和遵循的CAMediaTiming協(xié)議酌伊。
1腾窝、屬性:
-
@property(nullable, strong) CAMediaTimingFunction *timingFunction;
:時間函數(shù)用來定義動畫的節(jié)奏(速度控制函數(shù))。 默認(rèn)為nil居砖,表示線性運動虹脯。CAMediaTimingFunction類定義了速度控制函數(shù),共有四個函數(shù):-
+ (instancetype)functionWithName:(NSString *)name;
參數(shù)選項共有五個:-
CA_EXTERN NSString * const kCAMediaTimingFunctionLinear
:線性勻速運動奏候。 -
CA_EXTERN NSString * const kCAMediaTimingFunctionEaseIn
:動畫開始時會較慢循集,之后動畫會加速。 -
CA_EXTERN NSString * const kCAMediaTimingFunctionEaseOut
:動畫在開始時會較快蔗草,之后動畫速度減慢咒彤。 -
CA_EXTERN NSString * const kCAMediaTimingFunctionEaseInEaseOut
:動畫在開始和結(jié)束時速度較慢,中間時間段內(nèi)速度較快蕉世。 -
CA_EXTERN NSString * const kCAMediaTimingFunctionDefault
:和kCAMediaTimingFunctionEaseInEaseOut很類似蔼紧,但是加速和減速的過程都稍微有些慢。
-
-
+ (instancetype)functionWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y;
創(chuàng)建一個三次貝塞爾曲線來描述運動速度狀態(tài)的改變狠轻, 曲線的終點為(0,0)和(1,1)奸例,由類實例定義的兩個點'c1'和'c2'是控制點。 因此向楼,定義貝塞爾曲線的點是:'[(0,0), c1, c2, (1,1)]'即'[(0,0), (c1x,c1y), (c2x,c2y), (1,1)]' -
- (instancetype)initWithControlPoints:(float)c1x :(float)c1y :(float)c2x :(float)c2y;
同上查吊。 -
- (void)getControlPointAtIndex:(size_t)idx values:(float[2])ptr;
可以根據(jù)已知的CAMediaTimingFunction曲線,獲知其控制點湖蜕。
-
@property(nullable, strong) id <CAAnimationDelegate> delegate;
需要注意的是逻卖,這里是強(qiáng)引用,該對象在動畫對象的生命周期中被保留昭抒。 默認(rèn)為nil评也。@property(getter=isRemovedOnCompletion) BOOL removedOnCompletion;
該屬性控制當(dāng)動畫活動持續(xù)時間過去后,動畫是否從渲染樹中刪除灭返,即圖像恢復(fù)原狀盗迟。默認(rèn)是YES。一般不要設(shè)置為NO熙含,而是通過直接更改中心點方法去進(jìn)行操作圖像動畫結(jié)束后狀態(tài)罚缕。
2、代理方法:
- (void)animationDidStart:(CAAnimation *)aim;
動畫已近開始后調(diào)用怎静。- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
動畫已經(jīng)結(jié)束后調(diào)用邮弹,如果動畫結(jié)束后沒有被刪除則flag為YES黔衡。即當(dāng)removedOnCompletion
屬性為YES時flag為NO。反之則為YES腌乡。
3盟劫、CAMediaTiming協(xié)議
CAMediaTiming協(xié)議通過layer和animations實現(xiàn),它對一個分層的定時系統(tǒng)進(jìn)行建模导饲,每個對象描述從對象的父對象到自己本身本地時間的時間值的映射(有點拗口~)捞高。
?馬赫時間被定義為轉(zhuǎn)換為秒的絕對時間,系統(tǒng)提供了CACurrentMediaTime()
函數(shù)來實現(xiàn)此功能渣锦,方便查詢當(dāng)前的絕對時間(即從設(shè)備啟動后經(jīng)歷的時間的秒數(shù)硝岗,其實沒有實際意義,可以用來測試代碼效率袋毙,在這里作為參照時間使用型檀,不需要管實際值是多少)。
該協(xié)議共包括8個屬性:
@property CFTimeInterval beginTime;
指定動畫開始的時間(相對于其父對象)听盖,默認(rèn)為0胀溺。從開始延遲幾秒的話,設(shè)置為CACurrentMediaTime() + 秒數(shù)
的方式皆看。@property CFTimeInterval duration;
動畫持續(xù)時間仓坞,默認(rèn)為0。@property float speed;
layer層動畫速度腰吟,默認(rèn)為1无埃, 用于將父對象時間縮放到當(dāng)?shù)貢r間。例如如果速率為2毛雇,duration為3秒嫉称,則其實1.5秒后動畫就完成了。同樣該屬性值可以疊乘灵疮,因為CALayer也實現(xiàn)了相同的協(xié)議织阅,這就意味著你可以設(shè)置layer的speed為2.0,這樣震捣,所有加入到layer的動畫運行都要快兩倍荔棉。若設(shè)置此時設(shè)置animation的speed為2,則會比原來速度快4倍蒿赢!@property CFTimeInterval timeOffset;
動畫當(dāng)?shù)貢r間當(dāng)?shù)氐念~外偏移量江耀。 范圍是[0 - duration],是指從中間某一狀態(tài)開始诉植,然后將前面的部分補(bǔ)充到后面。一個用途是通過將“speed”設(shè)置為0并將“offset”設(shè)置為合適的值來“暫完枪郏”一層晾腔。 默認(rèn)為0舌稀。@property float repeatCount;
動畫重復(fù)次數(shù)。默認(rèn)為0灼擂。@property CFTimeInterval repeatDuration;
動畫重復(fù)持續(xù)時間壁查,默認(rèn)為0。例如剔应,duration為2.0睡腿,repeatCount為2,那么動畫完整持續(xù)時間應(yīng)該是4s峻贮,而且動畫也會按照4s的進(jìn)度進(jìn)行席怪,此時如果設(shè)置repeatDuration為2.0,則實際效果看起來動畫只運行了一遍沒有重復(fù)進(jìn)行纤控。@property BOOL autoreverses;
是否自動執(zhí)行動畫在向前播放后反向播放挂捻。默認(rèn)為NO。-
@property(copy) NSString *fillMode;
該屬性定義了定時對象在其活動持續(xù)時間之外的行為船万。系統(tǒng)提供了四個常量:CA_EXTERN NSString * const kCAFillModeForwards
:動畫向前延伸刻撒,所謂向前即向動畫持續(xù)的方向,在超出持續(xù)時間后耿导,如果removedOnCompletion設(shè)置為NO則會保持動畫最后的狀態(tài)声怔,直到手動調(diào)用removeAnimation方法。CA_EXTERN NSString * const kCAFillModeBackwards
:
將會立即執(zhí)行動畫的第一幀舱呻,不論是否設(shè)置了 beginTime屬性醋火,直到 beginTime 時開始正常動畫。CA_EXTERN NSString * const kCAFillModeBoth
:前兩者的集合狮荔。CA_EXTERN NSString * const kCAFillModeRemoved
:默認(rèn)情況胎撇,動畫完成后直接移除。
以上屬性均可組合使用殖氏,以達(dá)到理想的效果晚树。關(guān)于以上屬性間的關(guān)系可以參考一下下圖(關(guān)系圖),這里參考了 大衛(wèi)·羅恩奎斯特 的 Controlling Animation Timing雅采。這篇文章爵憎,在此表示非常的感謝!
一婚瓜、CAPropertyAnimation (屬性動畫)
CAPropertyAnimation是基于屬性的動畫子類宝鼓,它與CAAnimation一樣是一個抽象類 --- 不能直接使用,應(yīng)該使用其具體子類巴刻。共包含一個創(chuàng)建方法和四個屬性:
+ (instancetype)animationWithKeyPath:(nullable NSString *)path;
根據(jù)路徑創(chuàng)建對象愚铡,關(guān)于path可以參考該文章中 表2 部分@property(nullable, copy) NSString *keyPath;
即上面的path。@property(getter=isAdditive) BOOL additive;
如何處理多個動畫在同一時間段執(zhí)行的結(jié)果,若為YES沥寥,同一時間段的動畫合成為一個動畫碍舍,默認(rèn)為NO。(使用 CAKeyframeAnimation 時必須將該屬性指定為 YES 邑雅,否則不會出現(xiàn)期待的結(jié)果)@property(getter=isCumulative) BOOL cumulative
影響重復(fù)動畫如何產(chǎn)生結(jié)果片橡,若為YES,則動畫的當(dāng)前值是上一個重復(fù)周期結(jié)束時的值淮野,加上當(dāng)前重復(fù)周期的值捧书。 如果為NO,則該值只是為當(dāng)前重復(fù)周期計算的值骤星。 默認(rèn)為NO经瓷。-
@property(nullable, strong) CAValueFunction *valueFunction;
默認(rèn)為nil。該屬性值是一個CAValueFunction對象妈踊,該對象負(fù)責(zé)對屬性改變的插值計算了嚎,系統(tǒng)已經(jīng)提供了默認(rèn)的插值計算方式,因此一般無須指定該屬性廊营。- 關(guān)于CAValueFunction對象:
+ (nullable instancetype)functionWithName:(NSString *)name;
@property(readonly) NSString *name;
其中參數(shù)name由系統(tǒng)提供:
CA_EXTERN NSString * const kCAValueFunctionRotateX
CA_EXTERN NSString * const kCAValueFunctionRotateY
CA_EXTERN NSString * const kCAValueFunctionRotateZ
CA_EXTERN NSString * const kCAValueFunctionScale
CA_EXTERN NSString * const kCAValueFunctionScaleX
CA_EXTERN NSString * const kCAValueFunctionScaleY
CA_EXTERN NSString * const kCAValueFunctionScaleZ
CA_EXTERN NSString * const kCAValueFunctionTranslate
CA_EXTERN NSString * const kCAValueFunctionTranslateX
CA_EXTERN NSString * const kCAValueFunctionTranslateY
CA_EXTERN NSString * const kCAValueFunctionTranslateZ
1歪泳、CABaseAnimation(基礎(chǔ)動畫)
CABaseAnimation用來實現(xiàn)一些比較簡單的動畫比如平移、縮放露筒、旋轉(zhuǎn)等呐伞,它本身只有三個屬性,而且如果使用該動畫慎式,則至多有兩個值不為nil伶氢。
-
@property(nullable, strong) id fromValue;
動畫從哪個值開始,若為nil瘪吏,則從屬性當(dāng)前值開始動畫癣防。若只有該屬性不為nil,則動畫在屬性的fromValue和當(dāng)前值之間進(jìn)行掌眠! -
@property(nullable, strong) id toValue;
動畫到哪個值結(jié)束蕾盯。 -
@property(nullable, strong) id byValue;
動畫通過那個值。若只有該屬性不為nil蓝丙,則產(chǎn)生效果為 :toValue
=原屬性值
+byValue
级遭,然后按照這一目的值產(chǎn)生動畫。若只有fromValue和byValue不為nil渺尘,怎相當(dāng)于在fromValue
和(fromValue+ byValue
)之間產(chǎn)生動畫挫鸽。若只有toValue和byValue不為nil,則在(toValue-byValue
)和toValue
之間產(chǎn)生動畫鸥跟。若三者同時存在byValue不起作用6肌!!
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
CABasicAnimation * baseAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
baseAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
baseAnimation.duration = 5.0;
// baseAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(300, 500)];
// [self.redView.layer addAnimation:baseAnimation forKey:@"onlyFromValue"];
// baseAnimation.byValue = [NSValue valueWithCGPoint:CGPointMake(300, 500)];
// [self.redView.layer addAnimation:baseAnimation forKey:@"onlyByValue"];
// baseAnimation.byValue = [NSValue valueWithCGPoint:CGPointMake(100, 175)];
// baseAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 500)];
// [self.redView.layer addAnimation:baseAnimation forKey:@"byValue-toValue"];
baseAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(300, 200)];
baseAnimation.byValue = [NSValue valueWithCGPoint:CGPointMake(100, 175)];
baseAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 500)];
[self.redView.layer addAnimation:baseAnimation forKey:@"fromValue-byValue-toValue"];
}
2蚂夕、CAKeyFrameAnimation(關(guān)鍵幀動畫)
?關(guān)鍵幀動畫的值可以指定一個value數(shù)組或者一個路徑(CGPathRef)迅诬。和CABasicAnimation動畫相比,在同一時間內(nèi)對同一layer可以做多種不同動畫婿牍,并且可以控制各動畫的執(zhí)行節(jié)奏。
-
@property(nullable, copy) NSArray *values;
: 相當(dāng)于CABasicAnimation中只有的toValue情況惩歉,不過這里是一個toValue的集合等脂。 -
@property(nullable) CGPathRef path;
:定義動畫功能行為的可選路徑對象。 當(dāng)值非nil時撑蚌,會覆蓋values
屬性上遥。 除了moveto
點(起點)之外,路徑中的每個點都定義了一個關(guān)鍵幀争涌,用于定時和插值粉楚。 默認(rèn)為nil。 需要注意的是對于沿著路徑的恒速動畫亮垫,calculateMode
應(yīng)該設(shè)置為paced
而不是linear
模软。 -
@property(nullable, copy) NSArray<NSNumber *> *keyTimes;
:關(guān)鍵幀動畫每幀動畫開始執(zhí)行時間點的數(shù)組,取值范圍為0~1饮潦,即燃异,將duration
屬性單位化。一般情況下數(shù)組中相鄰兩個值必須遵循后一個值大于或等于前一個值叁温,并且最后的值不能為大于1逗抑。未設(shè)置時默認(rèn)每幀動畫執(zhí)行時間均分麦牺。 -
@property(nullable, copy) NSArray<CAMediaTimingFunction *> *timingFunctions;
:CAMediaTimingFunction對象的可選數(shù)組。 如果values
數(shù)組定義了n個關(guān)鍵幀仅颇,則在timingFunctions
數(shù)組中應(yīng)該有n-1個對象。 -
@property(copy) NSString *calculationMode;
:“計算模式”碘举。 可能的值為“discrete”忘瓦,“l(fā)inear”,“paced”殴俱,“cubic”和“cubicPaced”政冻。 默認(rèn)為“l(fā)inear”。 當(dāng)設(shè)置為“paced”或“cubicPaced”時线欲,動畫的keyTimes
和timingFunctions
屬性將被忽略并隱式計算明场。也可以用系統(tǒng)提供的常量參數(shù):CA_EXTERN NSString * const kCAAnimationLinear
CA_EXTERN NSString * const kCAAnimationDiscrete
CA_EXTERN NSString * const kCAAnimationPaced
CA_EXTERN NSString * const kCAAnimationCubic
CA_EXTERN NSString * const kCAAnimationCubicPaced
-
@property(nullable, copy) NSArray<NSNumber *> *tensionValues;
張力值、@property(nullable, copy) NSArray<NSNumber *> *continuityValues;
連續(xù)性值李丰、@property(nullable, copy) NSArray<NSNumber *> *biasValues;
偏置值苦锨。這些定義都是在三次曲線計算模式(cubic calculation modes)情況下才能起作用,對應(yīng)每一個控制點,取值范圍[-1, 1]舟舒。張力值控制曲線的“緊度”(正值更緊拉庶,負(fù)值更圓)。 連續(xù)性值控制段如何連接(正值給出銳角秃励,負(fù)值給出倒角)氏仗。 偏置值定義曲線出現(xiàn)位置(正值在控制點前移動曲線,負(fù)值在控制點后移動)夺鲜。 -
@property(nullable, copy) NSString *rotationMode;
:定義沿著路徑y(tǒng)運行體是否自動旋轉(zhuǎn)調(diào)整以使自身橫截面匹配路徑切線皆尔,默認(rèn)為nil。(只有設(shè)置了path
才有意義)币励。-
CA_EXTERN NSString * const kCAAnimationRotateAuto
自動匹配慷蠕。 -
CA_EXTERN NSString * const kCAAnimationRotateAutoReverse
在上一常量的基礎(chǔ)上順時針多旋轉(zhuǎn)180°。
-
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
CAKeyframeAnimation * keyFrameAni = [CAKeyframeAnimation animationWithKeyPath:@"position"];
keyFrameAni.duration = 10.0;
keyFrameAni.values = @[[NSValue valueWithCGPoint:CGPointMake(50, 100)], [NSValue valueWithCGPoint:CGPointMake(300, 100)], [NSValue valueWithCGPoint:CGPointMake(300, 500)], [NSValue valueWithCGPoint:CGPointMake(50, 500)],[NSValue valueWithCGPoint:CGPointMake(50, 100)]];
keyFrameAni.keyTimes = @[[NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:0.3], [NSNumber numberWithFloat:0.5], [NSNumber numberWithFloat:0.8], [NSNumber numberWithFloat:1.0]];
keyFrameAni.timingFunctions =@[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut], [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
if (!isPath) {
keyFrameAni.path = nil;
keyFrameAni.rotationMode = nil;
isPath = YES;
}else{
UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 100, 250, 400) byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(125, 125)];
keyFrameAni.path = path.CGPath;
keyFrameAni.calculationMode = kCAAnimationPaced;
keyFrameAni.rotationMode = kCAAnimationRotateAuto;
// keyFrameAni.rotationMode = kCAAnimationRotateAutoReverse;
isPath = NO;
}
[self.imageView.layer addAnimation:keyFrameAni forKey:@"noPath"];
}
看一下簡單的效果:
3食呻、CASpringAnimation(彈性動畫)
?彈性動畫父類是CABasicAnimation流炕,主要用來設(shè)置類似于緩沖、減速動畫仅胞。
-
@property CGFloat mass;
:質(zhì)量每辟,影響圖層運動時的彈簧慣性,質(zhì)量越大饼问,慣性越大影兽,彈簧拉伸和壓縮的幅度越大。該值必須大于0莱革,默認(rèn)為1峻堰。 -
@property CGFloat stiffness;
:彈簧剛度系數(shù),剛度系數(shù)越大盅视,形變產(chǎn)生的力就越大捐名,彈性運動越快,必須大于0闹击,默認(rèn)為100镶蹋。 -
@property CGFloat damping;
:阻尼/減幅,阻止彈簧伸縮的系數(shù)赏半,阻尼系數(shù)越大贺归,停止越快(可以看成阻力~),必須大于等于0断箫,默認(rèn)是10拂酣。 -
@property CGFloat initialVelocity;
:附著在彈簧上的物體的初始速度。 默認(rèn)為零仲义。速率為正數(shù)時婶熬,速度方向與運動方向一致剑勾,速率為負(fù)數(shù)時,速度方向會向與運動方向相反的方向先做運動赵颅。 -
@property(readonly) CFTimeInterval settlingDuration;
:返回估計的持續(xù)時間虽另。注意該屬性是只讀屬性, 針對當(dāng)前動畫參數(shù)評估持續(xù)時間饺谬。一般動畫使用該時間作為持續(xù)時間也是比較好的捂刺。
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.redView = [UIView new];
self.redView.frame = CGRectMake(175, 175, 100, 100);
self.redView.center = self.view.center;
self.redView.backgroundColor = [UIColor redColor];
self.redView.alpha = 0.5;
[self.view addSubview:self.redView];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
CASpringAnimation * springAni = [CASpringAnimation animationWithKeyPath:@"bounds.size"];
springAni.toValue = [NSValue valueWithCGSize:CGSizeMake(250, 100)];
springAni.mass = 5;
springAni.stiffness = 500;
springAni.damping = 15;
springAni.initialVelocity = -10;
springAni.duration = springAni.settlingDuration;
[self.redView.layer addAnimation:springAni forKey:@"spring"];
}
二、CATransition(轉(zhuǎn)場動畫)
?主要用于從一個場景向另一個場景的動畫過渡募寨。
-
@property(copy) NSString *type;
:轉(zhuǎn)場動畫的l類型系統(tǒng)公開的有:fade
,moveIn
,push
andreveal
. Defaults to `fade'叠萍。對應(yīng)系統(tǒng)常量:-
CA_EXTERN NSString * const kCATransitionFade
淡進(jìn)淡出; -
CA_EXTERN NSString * const kCATransitionMoveIn
新視圖移動到舊視圖上绪商; -
CA_EXTERN NSString * const kCATransitionPush
推出新視圖 -
CA_EXTERN NSString * const kCATransitionReveal
揭開顯示新視圖 - 除了公開的還有一些私有的:"cube"立方體翻轉(zhuǎn)效果、 "suckEffect"收縮效果辅鲸、 "rippleEffect"水滴波紋效果格郁、 "pageCurl"向上翻頁效果、
"pageUnCurl"向下翻頁效果独悴、 "oglFlip"翻轉(zhuǎn)效果例书、"cameraIrisHollowOpen"攝像頭打開效果、
"cameraIrisHollowClose"攝像頭關(guān)閉果刻炒。
-
-
@property(nullable, copy) NSString *subtype;
轉(zhuǎn)場方向决采,系統(tǒng)體供了四個:CA_EXTERN NSString * const kCATransitionFromRight
CA_EXTERN NSString * const kCATransitionFromLeft
CA_EXTERN NSString * const kCATransitionFromTop
CA_EXTERN NSString * const kCATransitionFromBottom
@property float startProgress;
開始進(jìn)度,默認(rèn)為0坟奥,范圍[0 , 1]树瞭,如果設(shè)置0.2,那么動畫將從動畫的0.2的部分開始。@property float endProgress;
結(jié)束進(jìn)度爱谁,默認(rèn)為1晒喷,范圍[0 , 1],如果設(shè)置0.7,那么動畫將從動畫的0.7的部分開始访敌。務(wù)必保證endProgress大于等于startProgress凉敲。@property(nullable, strong) id filter;
自定義過濾器,基本不會用~
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
i = -1;
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(50, 100, 275, 400)];
self.imageView.image = [UIImage imageNamed:@"boy"];
[self.view addSubview:self.imageView];
self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 550, 275, 50)];
self.nameLabel.backgroundColor = [UIColor redColor];
self.nameLabel.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:self.nameLabel];
self.imageNames = @[@"boy", @"loli", @"romance", @"poem", @"effort"];
self.animationTypes = @[kCATransitionFade, kCATransitionMoveIn, kCATransitionPush, kCATransitionReveal, @"cube", @"suckEffect", @"rippleEffect", @"pageCurl", @"pageUnCurl", @"oglFlip", @"cameraIrisHollowOpen", @"cameraIrisHollowClose"];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if (i == self.animationTypes.count-1) {
i = 0;
}else{
i = i+1;
}
CATransition * transition = [CATransition animation];
transition.duration = 2.0;
transition.type = self.animationTypes[i];
transition.subtype = kCATransitionFromRight;
self.imageView.image = [UIImage imageNamed:self.imageNames[i%5]];
self.nameLabel.text = self.animationTypes[i];
[self.imageView.layer addAnimation:transition forKey:@"transition"];
}
三寺旺、CAAnimationGroup(動畫組)
?只有一個屬性@property(nullable, copy) NSArray<CAAnimation *> *animations;
一組CAAnimation對象爷抓。 數(shù)組的每個成員將使用正常規(guī)則在父動畫的時間空間中同時運行(并發(fā))。
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
CABasicAnimation * baseAni = [CABasicAnimation animationWithKeyPath:@"transform"];
baseAni.duration = 5.0;
CATransform3D transform = CATransform3DMakeRotation(M_PI, 100, 100, 0);
baseAni.toValue =[NSValue valueWithCATransform3D:transform];
CASpringAnimation * springAni = [CASpringAnimation animationWithKeyPath:@"bounds.size"];
springAni.toValue = [NSValue valueWithCGSize:CGSizeMake(100, 220)];
springAni.mass = 2;
springAni.stiffness = 300;
springAni.damping = 5;
springAni.fillMode = kCAFillModeForwards;
springAni.duration = springAni.settlingDuration;
CAKeyframeAnimation * keyFrameAni = [CAKeyframeAnimation animationWithKeyPath:@"position"];
keyFrameAni.duration = 5.0;
UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 100, 250, 400) byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(125, 125)];
keyFrameAni.path = path.CGPath;
keyFrameAni.calculationMode = kCAAnimationPaced;
keyFrameAni.rotationMode = kCAAnimationRotateAuto;
CAAnimationGroup * groupAni = [CAAnimationGroup animation];
groupAni.animations = @[baseAni, springAni, keyFrameAni];
groupAni.duration = 5;
[self.imageView.layer addAnimation:groupAni forKey:@"group"];
}