CALayer
一攒读、簡(jiǎn)介
1.CALayer
簡(jiǎn)單的說(shuō)是層(圖層)的概念绸贡,類似與PS中的圖層。一個(gè)用來(lái)完成繪制凛辣、渲染抱既、動(dòng)畫(huà)等效果的可見(jiàn)的容器。
2.CALayer 與 UIView 的聯(lián)系與區(qū)別
UIView中有一個(gè)layer屬性扁誓,為根圖層防泵。UIView之所以能顯示在屏幕上,完全是因?yàn)樗鼉?nèi)部的CALayer對(duì)象蝗敢。在創(chuàng)建UIView對(duì)象時(shí)捷泞,UIView內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)層(即CALayer對(duì)象),通過(guò)UIView的layer屬性可以訪問(wèn)這個(gè)層寿谴。當(dāng)UIView需要顯示到屏幕上時(shí)锁右,會(huì)調(diào)用drawRect:方法進(jìn)行繪圖,并且會(huì)將所有內(nèi)容繪制在自己的層上,繪圖完畢后咏瑟,系統(tǒng)會(huì)將層拷貝到屏幕上拂到,于是就完成了UIView的顯示。UIView本身不具備顯示的功能码泞,顯示的是UIView的CALayer谆焊。
UIView可以通過(guò)subviews屬性訪問(wèn)所有的子視圖,同樣地浦夷,CALayer也可以通過(guò)sublayers屬性訪問(wèn)所有的子層;UIView可以通過(guò)superview屬性訪問(wèn)父視圖辜王,同樣地劈狐,CALayer也可以通過(guò)superlayer屬性訪問(wèn)父層。
UIView可以通過(guò)addSubview:方法添加子視圖呐馆,同樣地肥缔,CALayer可以通過(guò)addSublayer:方法添加子層。
在使用時(shí)汹来,往往CALayer和UIView都能實(shí)現(xiàn)相同的顯示效果续膳,但是UIView具有交互的能力,可以處理事件收班。如果顯示出來(lái)的東西需要跟用戶進(jìn)行交互的話坟岔,那么就要使用用UIView。
3.常用屬性
屬性 | 說(shuō)明 | 是否支持隱式動(dòng)畫(huà) |
---|---|---|
anchorPoint | 和中心點(diǎn)position重合的一個(gè)點(diǎn)摔桦,稱為“錨點(diǎn)”社付,錨點(diǎn)的描述是相對(duì)于x、y位置比例而言的默認(rèn)在圖像中心點(diǎn)(0.5,0.5)的位置 | 是 |
backgroundColor | 圖層背景顏色 | 是 |
borderColor | 邊框顏色 | 是 |
borderWidth | 邊框?qū)挾?/td> | 是 |
bounds | 圖層大小 | 是 |
contents | 圖層顯示的內(nèi)容 | 是 |
contentsRect | 圖層顯示內(nèi)容的大小和位置 | 是 |
cornerRadius | 圓角半徑 | 是 |
doubleSided | 圖層背面是否顯示邻耕,默認(rèn)為YES | 否 |
frame | 圖層大小和位置 | 否 |
hidden | 是否隱藏 | 是 |
mask | 圖層蒙版 | 是 |
maskToBounds | 子圖層是否剪切圖層邊界鸥咖,默認(rèn)為NO | 是 |
opacity | 透明度 | 是 |
position | 圖層中心點(diǎn)位置 | 是 |
shadowColor | 陰影顏色 | 是 |
shadowOffset | 陰影偏移量 | 是 |
shadowOpacity | 陰影透明度,默認(rèn)為0兄世,設(shè)置陰影必須設(shè)置此屬性 | 是 |
shadowPath | 陰影的形狀 | 是 |
shadowRadius | 陰影模糊半徑 | 是 |
sublayers | 子圖層 | 是 |
sublayerTransform | 子圖層形變 | 是 |
transform | 圖層形變 | 是 |
注:
- 在CALayer中很少使用frame屬性啼辣,因?yàn)閒rame本身不支持隱式動(dòng)畫(huà),通常使用bounds和position代替
- anchorPoint屬性是圖層的錨點(diǎn)御滩,范圍在(01,01)表示在x鸥拧、y軸的比例,這個(gè)點(diǎn)決定著CALayer身上的哪個(gè)點(diǎn)會(huì)與position所指定的位置重合削解,當(dāng)圖層中心點(diǎn)固定后住涉,調(diào)整anchorPoint即可達(dá)到調(diào)整圖層顯示位置的作用(因?yàn)樗肋h(yuǎn)和position重合)
4.隱式動(dòng)畫(huà)屬性
每一個(gè)UIView內(nèi)部都默認(rèn)關(guān)聯(lián)著一個(gè)CALayer,這個(gè)CALayer為Root Layer(根層)钠绍。對(duì)于所有的非Root Layer舆声,即手動(dòng)創(chuàng)建的CALayer對(duì)象,當(dāng)對(duì)非Root Layer的部分屬性進(jìn)行相應(yīng)的修改時(shí),默認(rèn)會(huì)自動(dòng)產(chǎn)生一些動(dòng)畫(huà)效果媳握,這些屬性稱為Animatable Properties(可動(dòng)畫(huà)屬性)碱屁。隱式屬性動(dòng)畫(huà)的本質(zhì)是這些屬性的變動(dòng)默認(rèn)隱含了CABasicAnimation動(dòng)畫(huà)實(shí)現(xiàn),例如修改bounds屬性會(huì)產(chǎn)生縮放動(dòng)畫(huà)蛾找,修改backgroundColor屬性會(huì)產(chǎn)生背景色的漸變動(dòng)畫(huà)娩脾,修改position屬性會(huì)產(chǎn)生平移動(dòng)畫(huà)。
可以通過(guò)動(dòng)畫(huà)事務(wù)(CATransaction)關(guān)閉默認(rèn)的隱式動(dòng)畫(huà)效果
[CATransactionbegin];
[CATransactionsetDisableActions:YES];
self.myview.layer.position= CGPointMake(100, 100);
[CATransactioncommit];
二打毛、簡(jiǎn)單使用
1. 設(shè)置陰影
imageView.layer.shadowColor = [UIColor grayColor].CGColor; //陰影顏色
imageView.layer.shadowOffset = CGSizeMake(10, 10); //陰影偏移量
imageView.layer.shadowOpacity = 0.5; //陰影透明度
2.設(shè)置圓角
imageView.layer.masksToBounds = YES;
imageView.layer.cornerRadius = 10; //當(dāng)cornerRadius等于邊長(zhǎng)的一半時(shí)柿赊,就是圓
3.設(shè)置邊框
imageView.layer.borderWidth = 5;
imageView.layer.borderColor = [UIColor redColor].CGColor;
4.設(shè)置旋轉(zhuǎn)
imageView.layer.transform = CATransform3DMakeRotation(M_PI_4, 0, 0, 1);// 順時(shí)針旋轉(zhuǎn)45
5.繪制圖層
繪制圖層有兩種方法
1.通過(guò)圖層代理drawLayer: inContext:方法繪制
2.通過(guò)自定義圖層drawInContext:方法繪制
不管使用哪種方法繪制完必須調(diào)用圖層的setNeedDisplay方法.
① 使用代理方法繪制圖層
通過(guò)代理方法進(jìn)行圖層繪圖只要指定圖層的代理,然后在代理對(duì)象中重寫-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx方法即可幻枉。需要注意這個(gè)方法雖然是代理方法但是不用手動(dòng)實(shí)現(xiàn)CALayerDelegate碰声,因?yàn)镃ALayer定義中給NSObject做了分類擴(kuò)展,所有的NSObject都包含這個(gè)方法熬甫。另外設(shè)置完代理后必須要調(diào)用圖層的setNeedDisplay方法胰挑,否則繪制的內(nèi)容無(wú)法顯示。
例
- (void)viewDidLoad {
[super viewDidLoad];
CALayer * layer = [[CALayer alloc]init];
layer.bounds = CGRectMake(0, 0, 100, 100);
layer.position = CGPointMake(50, 50);
layer.masksToBounds = YES;
layer.cornerRadius = 50;
layer.borderWidth = 2;
layer.borderColor = [UIColor yellowColor].CGColor;
layer.delegate = self; //設(shè)置代理
[self.view.layer addSublayer:layer]; //添加圖層
[layer setNeedsDisplay]; //重繪
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
CGContextSaveGState(ctx);
CGContextScaleCTM(ctx, 1, -1); //轉(zhuǎn)換坐標(biāo)系
CGContextTranslateCTM(ctx, 0, -100);
UIImage * image = [UIImage imageNamed:@"me"];
CGContextDrawImage(ctx, CGRectMake(0, 0, 100, 100), image.CGImage);
CGContextRestoreGState(ctx);
}
② 使用自定義圖層繪制圖層
創(chuàng)建一個(gè)CALayer的子類,然后重寫drawInContext:方法,在方法中使用Quartz2D API進(jìn)行繪圖蜀铲;
同樣,使用時(shí)贡这,必須要調(diào)用圖層的setNeedDisplay方法,才會(huì)觸發(fā)drawInContext:方法的調(diào)用厂榛。
Core Animation
一藕坯、簡(jiǎn)介
1.概念
Core Animation 是作用在CALayer上的,使用Core Animation 創(chuàng)建動(dòng)畫(huà)不僅簡(jiǎn)單噪沙,而且還有更好的性能炼彪,因?yàn)镃ore Animation 是在單獨(dú)的線程中完成的,不會(huì)阻塞主線程正歼,而且只會(huì)重繪界面上變化的部分(局部刷新)辐马。
2.分類
類別 | 說(shuō)明 |
---|---|
CAAnimation | 所有動(dòng)畫(huà)類的基類,不能直接使用局义,實(shí)現(xiàn)了CAMediaTiming協(xié)議喜爷,提供了動(dòng)畫(huà)的持續(xù)時(shí)間、速度和重復(fù)計(jì)數(shù)等萄唇,還實(shí)現(xiàn)了CAAction協(xié)議檩帐,該協(xié)議為CALayer動(dòng)畫(huà)觸發(fā)的動(dòng)作提供標(biāo)準(zhǔn)化響應(yīng)。 |
CATransition | CAAnimation的子類另萤,轉(zhuǎn)場(chǎng)動(dòng)畫(huà)湃密,能夠?yàn)閷犹峁┮瞥銎聊缓鸵迫肫聊坏膭?dòng)畫(huà)效果 |
CAAnimationGroup | CAAnimation的子類诅挑,動(dòng)畫(huà)組,是一種組合模式設(shè)計(jì)泛源,可以通過(guò)動(dòng)畫(huà)組來(lái)進(jìn)行所有動(dòng)畫(huà)行為的統(tǒng)一控制拔妥,組中所有動(dòng)畫(huà)效果可以并發(fā)執(zhí)行。 |
CAPropertyAnimation | CAAnimation的子類达箍,屬性動(dòng)畫(huà)的基類没龙,通過(guò)控制可動(dòng)畫(huà)屬性慢慢地變化,不能直接使用缎玫。有兩個(gè)子類CABasicAnimation 和 CAKeyframeAnimation硬纤。 |
CABasicAnimation | CAPropertyAnimation 的子類,基礎(chǔ)動(dòng)畫(huà)赃磨,簡(jiǎn)單地控制CALayer層的屬性慢慢改變筝家,從而實(shí)現(xiàn)動(dòng)畫(huà)。 |
CAKeyframeAnimation | CAPropertyAnimation 的子類煞躬,關(guān)鍵幀動(dòng)畫(huà),同樣是通過(guò)屬性進(jìn)行動(dòng)畫(huà)參數(shù)控制逸邦,通過(guò)values屬性指定多個(gè)關(guān)鍵幀恩沛,通過(guò)多個(gè)關(guān)鍵幀可以指定動(dòng)畫(huà)的各階段的關(guān)鍵值。 |
基礎(chǔ)動(dòng)畫(huà)缕减、關(guān)鍵幀動(dòng)畫(huà)都屬于屬性動(dòng)畫(huà)雷客,是通過(guò)修改屬性值產(chǎn)生動(dòng)畫(huà)效果,只需要設(shè)置初始值和結(jié)束值桥狡,中間的過(guò)程動(dòng)畫(huà)(“補(bǔ)間動(dòng)畫(huà)”)是由系統(tǒng)自動(dòng)計(jì)算產(chǎn)生搅裙。和基礎(chǔ)動(dòng)畫(huà)不同的是關(guān)鍵幀動(dòng)畫(huà)可以設(shè)置多個(gè)屬性值,每?jī)蓚€(gè)屬性中間的補(bǔ)間動(dòng)畫(huà)由系統(tǒng)自動(dòng)完成裹芝,基礎(chǔ)動(dòng)畫(huà)也可以看成是有兩個(gè)關(guān)鍵幀的關(guān)鍵幀動(dòng)畫(huà)部逮。
二、使用
1. CAAnimation
CAAnimation 是基類嫂易,其屬性它的子類也擁有兄朋。它不能直接使用。
屬性 | 說(shuō)明 |
---|---|
beginTime | 可以用來(lái)設(shè)置動(dòng)畫(huà)延遲執(zhí)行時(shí)間怜械,若想延遲2s颅和,就設(shè)置為CACurrentMediaTime()+2,CACurrentMediaTime()為圖層的當(dāng)前時(shí)間 |
duration | 動(dòng)畫(huà)的持續(xù)時(shí)間 |
delegate | 動(dòng)畫(huà)代理 |
repeatCount | 重復(fù)次數(shù)缕允,無(wú)限循環(huán)可以設(shè)置HUGE_VALF或者M(jìn)AXFLOAT |
repeatDuration | 重復(fù)時(shí)間 |
removedOnCompletion | 默認(rèn)為YES峡扩,代表動(dòng)畫(huà)執(zhí)行完畢后就從圖層上移除,圖形會(huì)恢復(fù)到動(dòng)畫(huà)執(zhí)行前的狀態(tài)障本。如果想讓圖層保持顯示動(dòng)畫(huà)執(zhí)行后的狀態(tài)教届,那就設(shè)置為NO,同時(shí)還要設(shè)置fillMode為kCAFillModeForwards |
fillMode | 決定當(dāng)前對(duì)象在非active時(shí)間段的行為。(要想fillMode有效巍佑,最好設(shè)置removedOnCompletion = NO)茴迁,kCAFillModeRemoved 這個(gè)是默認(rèn)值,也就是說(shuō)當(dāng)動(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)動(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 這個(gè)其實(shí)就是上面兩個(gè)的合成.動(dòng)畫(huà)加入后開(kāi)始之前秦踪,layer便處于動(dòng)畫(huà)初始狀態(tài)褐捻,動(dòng)畫(huà)結(jié)束后layer保持動(dòng)畫(huà)最后的狀態(tài) |
timingFunction | 速度控制函數(shù),控制動(dòng)畫(huà)運(yùn)行的節(jié)奏椅邓,為 CAMediaTimingFunction 類型柠逞。kCAMediaTimingFunctionLinear(線性):勻速動(dòng)畫(huà);kCAMediaTimingFunctionEaseIn(漸進(jìn)):動(dòng)畫(huà)緩慢進(jìn)入景馁,然后加速離開(kāi)板壮;kCAMediaTimingFunctionEaseOut(漸出):動(dòng)畫(huà)全速進(jìn)入,然后減速的到達(dá)目的地合住;kCAMediaTimingFunctionEaseInEaseOut(漸進(jìn)漸出):動(dòng)畫(huà)緩慢的進(jìn)入绰精,中間加速,然后減速的到達(dá)目的地透葛。 |
代理方法 : 給NSObject添加了分類笨使,所以任何對(duì)象,都可以成為CAAnimation的代理僚害。
動(dòng)畫(huà)開(kāi)始的時(shí)候調(diào)用 - (void)animationDidStart:(CAAnimation *)anim;
動(dòng)畫(huà)停止的時(shí)候調(diào)用 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
2.CAPropertyAnimation
屬性或方法 | 說(shuō)明 |
---|---|
+ (instancetype)animationWithKeyPath:(nullable NSString *)path; | 類方法阱表,創(chuàng)建一個(gè)新的動(dòng)畫(huà)對(duì)象,同時(shí)設(shè)置該對(duì)象的keyPath屬性 |
keyPath | 屬性贡珊,用來(lái)描述動(dòng)畫(huà)是作用在哪一個(gè)屬性上 |
additive | 屬性最爬,指定該屬性動(dòng)畫(huà)是否以當(dāng)前動(dòng)畫(huà)效果為基礎(chǔ) |
cumulative | 屬性,指定動(dòng)畫(huà)是否為累加效果 |
valueFunction | 該屬性值是一個(gè) CAValueFunction 對(duì)象门岔,負(fù)責(zé)對(duì)屬性改變進(jìn)行插值計(jì)算爱致,系統(tǒng)已經(jīng)提供了默認(rèn)的插值計(jì)算方式,一般無(wú)須指定該屬性寒随。 |
位移動(dòng)畫(huà)通常使用屬性動(dòng)畫(huà)控制 CALayer 的 position 屬性持續(xù)改變糠悯,如果要實(shí)現(xiàn) CALayer 的旋轉(zhuǎn)帮坚、縮放等動(dòng)畫(huà)效果,若在平面上(二維空間)上互艾,則修改 CALayer 的 affineTransform 屬性试和,該屬性值為一個(gè)CGAffineTransform 對(duì)象;若在三維空間上纫普,則修改 CALayer 的 transform 屬性阅悍,該屬性值為一個(gè) CATransform3D 對(duì)象。
CATransform3D : 三維變換矩陣
方法 | 說(shuō)明 |
---|---|
CATransform3DIsIdentity (CATransform3D t) | 返回bool值昨稼,判斷 t 矩陣是否為單位矩陣 |
CATransform3DEqualToTransform (CATransform3D a, CATransform3D b) | 返回bool值节视,判斷 a , b 兩個(gè)矩陣是否相等 |
CATransform3DMakeTranslation (CGFloat tx, CGFloat ty, CGFloat tz) | 創(chuàng)建一個(gè)在X方向上移動(dòng) tx、在Y方向上移動(dòng) ty假栓、在Z方向上移動(dòng) tz 的變化矩陣 |
CATransform3DMakeScale (CGFloat sx, CGFloat sy, CGFloat sz) | 創(chuàng)建一個(gè)在X方向上縮放 sx寻行、在Y方向上縮放 sy、在Z方向上縮放 sz 的變化矩陣 |
CATransform3DMakeRotation (CGFloat angle, CGFloat x, CGFloat y, CGFloat z) | 創(chuàng)建基于指定旋轉(zhuǎn)軸旋轉(zhuǎn) angle 弧度的變換匾荆,x拌蜘、y、z 用于確定旋轉(zhuǎn)軸牙丽,(1简卧,0,0)指定旋轉(zhuǎn)軸為X軸剩岳,(0贞滨,1入热,0)指定旋轉(zhuǎn)軸為Y軸拍棕,(0,0勺良,1)指定旋轉(zhuǎn)軸為Z軸 |
CATransform3DTranslate (CATransform3D t, CGFloat tx, CGFloat ty, CGFloat tz) | 在 t 變化矩陣的基礎(chǔ)上進(jìn)行位移變換 |
CATransform3DScale (CATransform3D t, CGFloat sx, CGFloat sy, CGFloat sz) | 在 t 變化矩陣的基礎(chǔ)上進(jìn)行縮放變換 |
CATransform3DRotate (CATransform3D t, CGFloat angle, CGFloat x, CGFloat y, CGFloat z) | 在 t 變化矩陣的基礎(chǔ)上進(jìn)行旋轉(zhuǎn)變換 |
CATransform3DConcat (CATransform3D a, CATransform3D b) | 將a绰播,b兩個(gè)矩陣相乘 |
CATransform3DInvert (CATransform3D t) | 對(duì) t 矩形進(jìn)行反轉(zhuǎn) |
CATransform3DMakeAffineTransform (CGAffineTransform m) | 將 CGAffineTransform 矩陣轉(zhuǎn)化成 CATransform3D 矩陣,轉(zhuǎn)化后也只有X尚困,Y維度上的變換 |
CATransform3DIsAffine (CATransform3D t) | 返回bool值蠢箩,判斷 t 矩陣是否是 CGAffineTransform 變換矩陣 |
CATransform3DGetAffineTransform (CATransform3D t) | 獲取 t 矩陣所包含的 CGAffineTransform 變換矩陣 |
3.CABasicAnimation 和 CAKeyframeAnimation
CAPropertyAnimation的子類,首先創(chuàng)建初始化一個(gè)CALayer事甜,初始化動(dòng)畫(huà)CABasicAnimation是設(shè)置 fromValue 和 toValue 谬泌,CAKeyframeAnimation是設(shè)置 values ,再設(shè)置其他動(dòng)畫(huà)屬性逻谦,將動(dòng)畫(huà)添加到圖層上掌实。
CALayer 為動(dòng)畫(huà)提供的方法
方法 | 說(shuō)明 |
---|---|
- (void)addAnimation:(CAAnimation *)anim forKey:(nullable NSString *)key | 為 CALayer 添加一個(gè)動(dòng)畫(huà),并為動(dòng)畫(huà)指定一個(gè)唯一標(biāo)識(shí) |
- (nullable CAAnimation *)animationForKey:(NSString *)key | 讓 CALayer 執(zhí)行 key 所對(duì)應(yīng)的動(dòng)畫(huà) |
- (void)removeAllAnimations | 刪除 CALayer 上添加的所有動(dòng)畫(huà) |
- (void)removeAnimationForKey:(NSString *)key | 刪除 key 所對(duì)應(yīng)的動(dòng)畫(huà) |
- (nullable NSArray<NSString *> *)animationKeys | 獲取 CALayer 上所有動(dòng)畫(huà)的 key 組成的數(shù)組 |
① 位移動(dòng)畫(huà)
CABasicAnimation
CABasicAnimation * anim = [CABasicAnimation animationWithKeyPath:@"position"];
anim.fromValue = [NSValue valueWithCGPoint:self.layer.position];
CGPoint toPoint = CGPointMake(300, 300);
anim.toValue = [NSValue valueWithCGPoint:toPoint];
anim.duration = 1.0;
self.layer.position = toPoint;
anim.removedOnCompletion = YES;
[self.layer addAnimation:anim forKey:@"KCBasicAnimation_Position"];
CAKeyframeAnimation
CAKeyframeAnimation * keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
NSValue * value1 = [NSValue valueWithCGPoint:self.layer.position];
NSValue * value2 = [NSValue valueWithCGPoint:CGPointMake(80, 220)];
NSValue * value3 = [NSValue valueWithCGPoint:CGPointMake(45, 300)];
NSValue * value4 = [NSValue valueWithCGPoint:CGPointMake(55, 400)];
NSArray * values=@[value1,value2,value3,value4];
keyframeAnimation.values = values;
keyframeAnimation.duration = 2.0;
[self.layer addAnimation:keyframeAnimation forKey:@"KCKeyframeAnimation_Position"];
通過(guò)描繪路徑進(jìn)行關(guān)鍵幀動(dòng)畫(huà)控制
CAKeyframeAnimation * keyframeAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"];
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, self.layer.position.x, self.layer.position.y);
CGPathAddCurveToPoint(path, NULL, 160, 280, -30, 300, 55, 400);
keyframeAnimation.path = path;
CGPathRelease(path);
keyframeAnimation.duration = 4.0;
keyframeAnimation.removedOnCompletion = YES;
[self.layer addAnimation:keyframeAnimation forKey:@"KCKeyframeAnimation_Position"];
② 旋轉(zhuǎn)動(dòng)畫(huà)
CABasicAnimation
CABasicAnimation * anim = [CABasicAnimation animationWithKeyPath:@"transform"];
CATransform3D fromValue = self.layer.transform;
anim.fromValue = [NSValue valueWithCATransform3D:fromValue];
CATransform3D toValue = CATransform3DRotate(fromValue, M_PI, 1, 0, 0);
anim.toValue = [NSValue valueWithCATransform3D:toValue];
anim.duration = 0.5;
self.layer.transform = toValue;
anim.removedOnCompletion = YES;
[self.layer addAnimation:anim forKey:@"KCBasicAnimation_Rotate"];
CAKeyframeAnimation
CAKeyframeAnimation * keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
NSValue * value1 = [NSValue valueWithCATransform3D:self.layer.transform];
NSValue * value2 = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 1, 0, 0)];
NSValue * value3 = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 0, 1, 0)];
NSValue * value4 = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 0, 0, 1)];
NSArray * values = @[value1,value2,value3,value4];
keyframeAnimation.values = values;
keyframeAnimation.duration = 2.0;
[self.layer addAnimation:keyframeAnimation forKey:@"KCKeyframeAnimation_Rotate"];
③ 縮放動(dòng)畫(huà)
CABasicAnimation
CABasicAnimation * anim = [CABasicAnimation animationWithKeyPath:@"transform"];
CATransform3D fromValue = self.layer.transform;
anim.fromValue = [NSValue valueWithCATransform3D:fromValue];
CATransform3D toValue = CATransform3DScale(fromValue, 0.5, 0.5, 1);
anim.toValue = [NSValue valueWithCATransform3D:toValue];
anim.duration = 0.5;
self.layer.transform = toValue;
anim.removedOnCompletion = YES;
[self.layer addAnimation:anim forKey:@"KCBasicAnimation_Scale"];
CAKeyframeAnimation
CAKeyframeAnimation * keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
NSValue * value1 = [NSValue valueWithCATransform3D:self.layer.transform];
NSValue * value2 = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.5, 0.5, 1)];
NSValue * value3 = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1, 1, 1)];
NSArray * values = @[value1,value2,value3];
keyframeAnimation.values = values;
keyframeAnimation.duration = 2.0;
[self.layer addAnimation:keyframeAnimation forKey:@"KCKeyframeAnimation_Scale"];
④ 動(dòng)畫(huà)組
CABasicAnimation
CGPoint fromPoint = self.layer.position;
CGPoint toPoint = CGPointMake(280, fromPoint.y + 300);
CABasicAnimation * moveAnim = [CABasicAnimation animationWithKeyPath:@"position"];
moveAnim.fromValue = [NSValue valueWithCGPoint:fromPoint];
moveAnim.toValue = [NSValue valueWithCGPoint:toPoint];
moveAnim.removedOnCompletion = YES;
CABasicAnimation * transformAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
CATransform3D fromValue = self.layer.transform;
transformAnim.fromValue = [NSValue valueWithCATransform3D:fromValue];
CATransform3D scaleValue = CATransform3DScale(fromValue, 0.5, 0.5, 1);
CATransform3D rotateValue = CATransform3DRotate(fromValue, M_PI, 0, 0, 1);
CATransform3D toValue = CATransform3DConcat(scaleValue, rotateValue);
transformAnim.toValue = [NSValue valueWithCATransform3D:toValue];
transformAnim.cumulative = YES;
transformAnim.repeatCount = 2;
transformAnim.duration = 3;
CAAnimationGroup * animGroup = [CAAnimationGroup animation];
animGroup.animations = @[moveAnim,transformAnim];
animGroup.duration = 6;
[self.layer addAnimation:animGroup forKey:@"KCBasicAnimation_Group"];
CAKeyframeAnimation
CAKeyframeAnimation * moveAnim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
NSValue * move1 = [NSValue valueWithCGPoint:self.layer.position];
NSValue * move2 = [NSValue valueWithCGPoint:CGPointMake(300, 100)];
NSValue * move3 = [NSValue valueWithCGPoint:CGPointMake(300, 300)];
NSValue * move4 = [NSValue valueWithCGPoint:CGPointMake(100, 300)];
NSValue * move5 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
NSArray * values = @[move1,move2,move3,move4,move5];
moveAnim.values = values;
moveAnim.removedOnCompletion = YES;
CAKeyframeAnimation * transformAnim = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
CATransform3D rotate1 = self.layer.transform;
CATransform3D rotate2 = CATransform3DMakeRotation(M_PI, 1, 0, 0);
CATransform3D rotate3 = CATransform3DMakeRotation(M_PI, 0, 1, 0);
CATransform3D rotate4 = CATransform3DMakeRotation(M_PI, 0, 0, 1);
CATransform3D rotate5 = CATransform3DMakeRotation(M_PI, 1, 1, 1);
CATransform3D scale1 = self.layer.transform;
CATransform3D scale2 = CATransform3DMakeScale(0.5, 0.5, 1);
CATransform3D scale3 = CATransform3DMakeScale(1, 1, 1);
CATransform3D scale4 = CATransform3DMakeScale(0.5, 0.5, 1);
CATransform3D scale5 = CATransform3DMakeScale(1, 1, 1);
NSValue * transform1 = [NSValue valueWithCATransform3D:CATransform3DConcat(rotate1, scale1)];
NSValue * transform2 = [NSValue valueWithCATransform3D:CATransform3DConcat(rotate2, scale2)];
NSValue * transform3 = [NSValue valueWithCATransform3D:CATransform3DConcat(rotate3, scale3)];
NSValue * transform4 = [NSValue valueWithCATransform3D:CATransform3DConcat(rotate4, scale4)];
NSValue * transform5 = [NSValue valueWithCATransform3D:CATransform3DConcat(rotate5, scale5)];
transformAnim.values = @[transform1,transform2,transform3,transform4,transform5];
transformAnim.removedOnCompletion = YES;
CAAnimationGroup * animGroup = [CAAnimationGroup animation];
animGroup.animations = @[moveAnim,transformAnim];
animGroup.duration = 8;
self.layer.position = CGPointMake(100, 100);
[self.layer addAnimation:animGroup forKey:@"KCBasicAnimation_Group"];
④ 動(dòng)畫(huà)暫停
-(void)pauseLayer{
CFTimeInterval interval=[self.layer convertTime:CACurrentMediaTime() fromLayer:nil];
[self.layer setTimeOffset:interval];
self.layer.speed=0;
}
⑤ 動(dòng)畫(huà)恢復(fù)
-(void)resumeLayer{
CFTimeInterval beginTime= CACurrentMediaTime() - self.layer.timeOffset;
self.layer.timeOffset = 0;
self.layer.beginTime = beginTime;
self.layer.speed=1.0;
}
4.CATransition
屬性 | 說(shuō)明 |
---|---|
type | 動(dòng)畫(huà)過(guò)渡效果 |
subtype | 動(dòng)畫(huà)過(guò)渡方向 |
startProgress | 動(dòng)畫(huà)起點(diǎn)(在整體動(dòng)畫(huà)的百分比) |
endProgress | 動(dòng)畫(huà)終點(diǎn)(在整體動(dòng)畫(huà)的百分比) |
CATransition的type屬性用于控制動(dòng)畫(huà)類型邦马,還有私有動(dòng)畫(huà)贱鼻。
值| 說(shuō)明 |是否支持方向設(shè)置
-----|-----
kCATransitionFade|通過(guò)漸隱效果過(guò)渡宴卖,默認(rèn)屬性值|是
kCATransitionMoveIn|通過(guò)移入動(dòng)畫(huà)過(guò)渡,新視圖移到舊視圖上面|是
kCATransitionPush|通過(guò)推入動(dòng)畫(huà)過(guò)渡邻悬,新視圖把舊視圖推出去|是
kCATransitionReveal|通過(guò)揭開(kāi)動(dòng)畫(huà)過(guò)渡症昏,將舊視圖移開(kāi),同時(shí)顯示下面的新視圖|是
@"cube"|通過(guò)立方體旋轉(zhuǎn)動(dòng)畫(huà)過(guò)渡|是
@"oglFlip"|通過(guò)翻轉(zhuǎn)動(dòng)畫(huà)過(guò)渡|是
@"suckEffect"|通過(guò)收縮(吸入)動(dòng)畫(huà)過(guò)渡|否
@"rippleEffect"|通過(guò)水波動(dòng)畫(huà)過(guò)渡|否
@"pageCurl"|通過(guò)向后翻頁(yè)動(dòng)畫(huà)過(guò)渡|是
@"pageUnCurl"|通過(guò)向前翻頁(yè)動(dòng)畫(huà)過(guò)渡|是
@"cameraIrisHollowOpen"|通過(guò)相機(jī)鏡頭打開(kāi)效果動(dòng)畫(huà)過(guò)渡|否
@"cameraIrisHollowClose"|通過(guò)相機(jī)鏡頭關(guān)閉效果動(dòng)畫(huà)過(guò)渡|否
CATransition的subtype屬性用于控制動(dòng)畫(huà)方向
值 | 說(shuō)明 |
---|---|
kCATransitionFromRight | 從右側(cè)轉(zhuǎn)場(chǎng) |
kCATransitionFromLeft | 從左側(cè)轉(zhuǎn)場(chǎng) |
kCATransitionFromTop | 從頂部轉(zhuǎn)場(chǎng) |
kCATransitionFromBottom | 從底部轉(zhuǎn)場(chǎng) |
#import "ViewController.h"
#define IMAGE_COUNT 5
typedef enum {
GestureDirectionUp = 1,
GestureDirectionDown,
GestureDirectionLeft,
GestureDirectionRight
}GestureDirection;
@interface ViewController () <UIPickerViewDelegate,UIPickerViewDataSource>
@property (nonatomic,strong) UIImageView * imageView;
@property (nonatomic,assign) int currentIndex;
@property (nonatomic,strong) CATransition * transition;
@property (nonatomic,strong) UIPickerView * pickerView;
@property (nonatomic,copy) NSArray * transitions;
@property (nonatomic,assign) BOOL isPop;
@end
@implementation ViewController
- (NSArray *)transitions{
if (_transitions == nil) {
_transitions = @[kCATransitionFade,kCATransitionMoveIn,kCATransitionPush,kCATransitionReveal,@"cube",@"oglFlip",@"suckEffect",@"rippleEffect",@"pageCurl",@"pageUnCurl",@"cameralIrisHollowOpen",@"cameraIrisHollowClose"];
}
return _transitions;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
self.navigationItem.title = @"轉(zhuǎn)場(chǎng)";
UIBarButtonItem * rightBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"效果" style:UIBarButtonItemStyleDone target:self action:@selector(selectTransition:)];
self.navigationItem.rightBarButtonItem = rightBarButtonItem;
self.imageView = [[UIImageView alloc]initWithFrame:self.view.frame];
self.imageView.backgroundColor = [UIColor whiteColor];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.imageView.image = [UIImage imageNamed:@"0.jpg"];
[self.view addSubview:self.imageView];
self.pickerView = [[UIPickerView alloc]initWithFrame:CGRectMake(0, screenHeight, screenWidth, 300)];
self.pickerView.dataSource = self;
self.pickerView.delegate = self;
[self.view addSubview:self.pickerView];
UISwipeGestureRecognizer * upSwipeGesture = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
[upSwipeGesture setDirection:UISwipeGestureRecognizerDirectionUp];
[self.view addGestureRecognizer:upSwipeGesture];
UISwipeGestureRecognizer * downSwipeGesture = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
[downSwipeGesture setDirection:UISwipeGestureRecognizerDirectionDown];
[self.view addGestureRecognizer:downSwipeGesture];
UISwipeGestureRecognizer * leftSwipeGesture = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
[leftSwipeGesture setDirection:UISwipeGestureRecognizerDirectionLeft];
[self.view addGestureRecognizer:leftSwipeGesture];
UISwipeGestureRecognizer * rightSwipeGesture = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
[rightSwipeGesture setDirection:UISwipeGestureRecognizerDirectionRight];
[self.view addGestureRecognizer:rightSwipeGesture];
self.transition = [[CATransition alloc]init];
self.transition.type = kCATransitionFade;
self.isPop = NO;
}
- (void)selectTransition:(UIBarButtonItem *)btn{
self.isPop = !self.isPop;
if (self.isPop) {
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.6];
[self.view bringSubviewToFront:self.pickerView];
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
CGFloat pickerViewWidth = [UIScreen mainScreen].bounds.size.width;
CGFloat pickerViewHeight = 300;
self.pickerView.frame = CGRectMake(0, screenHeight - pickerViewHeight, pickerViewWidth, pickerViewHeight);
[UIView commitAnimations];
}
else {
CGContextRef context = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:context];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.6];
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
CGFloat pickerViewWidth = [UIScreen mainScreen].bounds.size.width;
CGFloat pickerViewHeight = 300;
self.pickerView.frame = CGRectMake(0, screenHeight, pickerViewWidth, pickerViewHeight);
[UIView commitAnimations];
}
}
-(void)swipe:(UISwipeGestureRecognizer *)gesture{
if (gesture.direction == UISwipeGestureRecognizerDirectionUp){
[self transitionAnimation:GestureDirectionUp];
}
else if (gesture.direction == UISwipeGestureRecognizerDirectionDown){
[self transitionAnimation:GestureDirectionDown];
}
else if (gesture.direction == UISwipeGestureRecognizerDirectionLeft){
[self transitionAnimation:GestureDirectionLeft];
}
else {
[self transitionAnimation:GestureDirectionRight];
}
}
- (void)transitionAnimation:(GestureDirection)gestureDirection{
switch (gestureDirection) {
case GestureDirectionUp:
self.transition.subtype = kCATransitionFromTop;
break;
case GestureDirectionDown:
self.transition.subtype = kCATransitionFromBottom;
break;
case GestureDirectionLeft:
self.transition.subtype = kCATransitionFromRight;
break;
case GestureDirectionRight:
self.transition.subtype = kCATransitionFromLeft;
break;
default:
break;
}
self.transition.duration = 1.0f;
self.imageView.image = [self getImage];
[self.view.layer addAnimation:self.transition forKey:@"KCTransitionAnimation"];
}
- (UIImage *)getImage{
self.currentIndex = (self.currentIndex + 1) % IMAGE_COUNT;
NSString *imageName=[NSString stringWithFormat:@"%i.jpg",_currentIndex];
return [UIImage imageNamed:imageName];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return self.transitions.count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return self.transitions[row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
self.transition.type = self.transitions[row];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
5.逐幀動(dòng)畫(huà)
通過(guò)設(shè)置UIImageView的animationImages屬性,然后調(diào)用它的startAnimating方法去播放一組逐幀圖片父丰,但是它存在著很大的性能問(wèn)題肝谭,并且這種方法一旦設(shè)置完圖片中間的過(guò)程就無(wú)法控制了。使用CADisplayLink加入到主循環(huán)隊(duì)列中础米,循環(huán)調(diào)用目標(biāo)方法分苇,在這個(gè)方法中更新視圖內(nèi)容就可以完成逐幀動(dòng)畫(huà)。
- (void)runAnimationWithImageCount:(NSInteger)count AndImageName:(NSString *)name
{
if (self.myImageView.isAnimating)
{
return;
}
NSMutableArray * pictArray = [NSMutableArray array];
for (int i = 0; i < count; i++)
{
NSString * pictNum = [NSString stringWithFormat:@"%@_%02d.jpg",name,i];
// 使用imageNamed的方式加載圖片會(huì)有緩存屁桑,使得占用的內(nèi)存很大
//[pictArray addObject:[UIImage imageNamed:pictNum]];
// 直接從文件中讀取圖片就不會(huì)占用太大的內(nèi)存
NSBundle * boudle = [NSBundle mainBundle];
NSString * path = [boudle pathForResource:pictNum ofType:nil];
[pictArray addObject:[UIImage imageWithContentsOfFile:path]];
}
self.myImageView.animationImages = pictArray;
self.myImageView.animationDuration = (self.myImageView.animationImages.count * 0.07);
CGFloat delayTime = self.myImageView.animationDuration + 0.5;
self.myImageView.animationRepeatCount = 1;
[self.myImageView startAnimating];
[self.myImageView performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:delayTime];
}
6.UIView動(dòng)畫(huà)封裝
UIView本身對(duì)于基本動(dòng)畫(huà)和關(guān)鍵幀動(dòng)畫(huà)医寿、轉(zhuǎn)場(chǎng)動(dòng)畫(huà)都有相應(yīng)的封裝。
方法 | 說(shuō)明 |
---|---|
+ (void)beginAnimations:(nullable NSString *)animationID context:(nullable void *)context | 開(kāi)始動(dòng)畫(huà)蘑斧,animationID :動(dòng)畫(huà)塊內(nèi)部應(yīng)用程序標(biāo)識(shí)靖秩,context :附加的信息,都傳遞給動(dòng)畫(huà)代理 |
+ (void)commitAnimations | 提交動(dòng)畫(huà)竖瘾,結(jié)束動(dòng)畫(huà) |
+ (void)setAnimationDelegate:(nullable id)delegate | 設(shè)置動(dòng)畫(huà)的代理 |
+ (void)setAnimationWillStartSelector:(nullable SEL)selector | 設(shè)置動(dòng)畫(huà)開(kāi)始時(shí)的執(zhí)行方法 |
+ (void)setAnimationDidStopSelector:(nullable SEL)selector | 設(shè)置動(dòng)畫(huà)結(jié)束時(shí)的執(zhí)行方法 |
+ (void)setAnimationDuration:(NSTimeInterval)duration | 設(shè)置動(dòng)畫(huà)執(zhí)行時(shí)間 |
+ (void)setAnimationDelay:(NSTimeInterval)delay | 設(shè)置動(dòng)畫(huà)延遲執(zhí)行的時(shí)間 |
+ (void)setAnimationStartDate:(NSDate *)startDate | 設(shè)置動(dòng)畫(huà)開(kāi)始執(zhí)行的時(shí)間 |
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve | 設(shè)置動(dòng)畫(huà)運(yùn)行過(guò)程中相對(duì)的速度 |
+ (void)setAnimationRepeatCount:(float)repeatCount | 設(shè)置動(dòng)畫(huà)重復(fù)次數(shù) |
+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses | 設(shè)置是否自動(dòng)逆向動(dòng)畫(huà) |
+ (void)setAnimationBeginsFromCurrentState:(BOOL)fromCurrentState | 設(shè)置動(dòng)畫(huà)是否從當(dāng)前狀態(tài)開(kāi)始執(zhí)行沟突,設(shè)置為YES,則當(dāng)上一次動(dòng)畫(huà)正在執(zhí)行中捕传,那么當(dāng)下一個(gè)動(dòng)畫(huà)開(kāi)始時(shí)惠拭,上一次動(dòng)畫(huà)的當(dāng)前狀態(tài)將成為下一次動(dòng)畫(huà)的開(kāi)始狀態(tài)。設(shè)置為NO庸论,則當(dāng)上一個(gè)動(dòng)畫(huà)正在執(zhí)行中职辅,那么當(dāng)下一個(gè)動(dòng)畫(huà)開(kāi)始時(shí),上一次動(dòng)畫(huà)需要先恢復(fù)到完成時(shí)的狀態(tài)聂示,然后在開(kāi)始執(zhí)行下一次動(dòng)畫(huà) |
+ (void)setAnimationsEnabled:(BOOL)enabled | 設(shè)置動(dòng)畫(huà)是否可用 |
+ (BOOL)areAnimationsEnabled | 獲取動(dòng)畫(huà)是否可用 |
動(dòng)畫(huà)使用block方式
方法 | 說(shuō)明 |
---|---|
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations | 使用block方式 |
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion | 使用block方式域携,有完成后的block |
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion | 使用block方式,可以設(shè)置動(dòng)畫(huà)延遲時(shí)間和動(dòng)畫(huà)參數(shù) |
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))animations completion:(void (^ __nullable)(BOOL finished))completion | 轉(zhuǎn)場(chǎng)動(dòng)畫(huà) |
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^ __nullable)(BOOL finished))completion | 轉(zhuǎn)場(chǎng)動(dòng)畫(huà)鱼喉,toView添加到fromView的父視圖中秀鞭,fromView從它的福視圖中移除 |
+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion | 使用block方式實(shí)現(xiàn)關(guān)鍵幀動(dòng)畫(huà) |
+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations | 從開(kāi)始時(shí)間添加一個(gè)持續(xù)時(shí)間的動(dòng)畫(huà) |
UIViewAnimationCurve
值 | 說(shuō)明 |
---|---|
UIViewAnimationCurveEaseIn | 先慢后快,在動(dòng)畫(huà)剛開(kāi)始的時(shí)候執(zhí)行速度慢 |
UIViewAnimationCurveEaseOut | 先快后慢扛禽,在動(dòng)畫(huà)快結(jié)束的時(shí)候執(zhí)行速度慢 |
UIViewAnimationCurveEaseInOut | 先由慢變快锋边,然后再變慢,在動(dòng)畫(huà)剛開(kāi)始和快結(jié)束的時(shí)候速度慢 |
UIViewAnimationCurveLinear | 勻速運(yùn)行 |
UIViewAnimationOptions
值 | 說(shuō)明 |
---|---|
UIViewAnimationOptionLayoutSubviews | 動(dòng)畫(huà)過(guò)程中保證子視圖跟隨運(yùn)動(dòng) |
UIViewAnimationOptionAllowUserInteraction | 動(dòng)畫(huà)過(guò)程中允許用戶交互 |
UIViewAnimationOptionBeginFromCurrentState | 所有視圖從當(dāng)前狀態(tài)開(kāi)始運(yùn)行 |
UIViewAnimationOptionRepeat | 重復(fù)執(zhí)行動(dòng)畫(huà) |
UIViewAnimationOptionAutoreverse | 逆向動(dòng)畫(huà)编曼,動(dòng)畫(huà)運(yùn)行到結(jié)束點(diǎn)后仍然以動(dòng)畫(huà)方式回到初始點(diǎn) |
UIViewAnimationOptionOverrideInheritedDuration | 忽略嵌套動(dòng)畫(huà)時(shí)間設(shè)置 |
UIViewAnimationOptionOverrideInheritedCurve | 忽略嵌套動(dòng)畫(huà)速度設(shè)置 |
UIViewAnimationOptionAllowAnimatedContent | 動(dòng)畫(huà)過(guò)程允許重繪視圖(僅適用在轉(zhuǎn)場(chǎng)動(dòng)畫(huà)中) |
UIViewAnimationOptionShowHideTransitionViews | 視圖切換時(shí)翻轉(zhuǎn)隱藏舊視圖豆巨、顯示新視圖,而不再是直接刪除舊視圖灵巧、添加新視圖 |
UIViewAnimationOptionOverrideInheritedOptions | 不繼承任何參數(shù)或動(dòng)畫(huà)類型 |
UIViewAnimationOptionCurveEaseInOut | 默認(rèn)值搀矫,和UIViewAnimationCurveEaseInOut效果一樣抹沪,只是這個(gè)值用于block動(dòng)畫(huà)參數(shù),先由慢變快瓤球,然后再變慢融欧,在動(dòng)畫(huà)剛開(kāi)始和快結(jié)束的時(shí)候速度慢 |
UIViewAnimationOptionCurveEaseIn | 和UIViewAnimationCurveEaseIn效果一樣,先慢后快卦羡,在動(dòng)畫(huà)剛開(kāi)始的時(shí)候執(zhí)行速度慢 |
UIViewAnimationOptionCurveEaseOut | 和UIViewAnimationCurveEaseOut效果一樣噪馏,先快后慢,在動(dòng)畫(huà)快結(jié)束的時(shí)候執(zhí)行速度慢 |
UIViewAnimationOptionCurveLinear | 和UIViewAnimationCurveLinear效果一樣绿饵,勻速運(yùn)行 |
UIViewAnimationOptionTransitionNone | 下面的值僅適用于轉(zhuǎn)場(chǎng)動(dòng)畫(huà)設(shè)置欠肾,沒(méi)有轉(zhuǎn)場(chǎng)動(dòng)畫(huà)效果 |
UIViewAnimationOptionTransitionFlipFromLeft | 從左側(cè)翻轉(zhuǎn) |
UIViewAnimationOptionTransitionFlipFromRight | 從右側(cè)翻轉(zhuǎn) |
UIViewAnimationOptionTransitionCurlUp | 向后翻頁(yè)的動(dòng)畫(huà)過(guò)渡 |
UIViewAnimationOptionTransitionCrossDissolve | 水波動(dòng)畫(huà)過(guò)渡 |
UIViewAnimationOptionTransitionFlipFromTop | 從頂部翻轉(zhuǎn) |
UIViewAnimationOptionTransitionFlipFromBottom | 從底部翻轉(zhuǎn) |
UIViewKeyframeAnimationOptions
其中一部分值和 UIViewAnimationOptions 是一樣的,不一樣的如下:
值 | 說(shuō)明 |
---|---|
UIViewKeyframeAnimationOptionCalculationModeLinear | 連續(xù)運(yùn)算模式 |
UIViewKeyframeAnimationOptionCalculationModeDiscrete | 離散運(yùn)算模式 |
UIViewKeyframeAnimationOptionCalculationModePaced | 均勻執(zhí)行運(yùn)算模式 |
UIViewKeyframeAnimationOptionCalculationModeCubic | 平滑運(yùn)算模式 |
UIViewKeyframeAnimationOptionCalculationModeCubicPaced | 平滑均勻運(yùn)算模式 |
7.彈簧動(dòng)畫(huà)
方法 | 說(shuō)明 |
---|---|
+ (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 | UIViewAnimationWithBlocks中的方法拟赊,用來(lái)創(chuàng)建具有彈簧效果的動(dòng)畫(huà)刺桃。dampingRatio為阻尼,范圍0~1吸祟,阻尼越接近于0瑟慈,彈性效果越明顯。velocity為彈性復(fù)位的速度屋匕。 |
[UIView animateWithDuration:5.0 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveLinear animations:^{
self.imageView.center = CGPointMake(300, 300);
} completion:nil];