作為一個(gè)IOS開發(fā)者,你肯定會(huì)遇到很多需求,比如。。。動(dòng)畫
一些簡(jiǎn)單的動(dòng)畫比如:放大、縮小、動(dòng)畫直線位移·······
一些稍微復(fù)雜的動(dòng)畫比如:抖動(dòng)、動(dòng)畫曲線位移······
一些動(dòng)畫的組合:放大位移,放大連續(xù)位移等等······
現(xiàn)在就給大家講一下一些動(dòng)畫的用法
Core Animation是IOS和OS X平臺(tái)上負(fù)責(zé)圖形渲染與動(dòng)畫的基礎(chǔ)框架。Core Animation可以作用與動(dòng)畫視圖或者其他可視元素,為你完成了動(dòng)畫所需的大部分繪幀工作。你只需要配置少量的動(dòng)畫參數(shù)(如開始點(diǎn)的位置和結(jié)束點(diǎn)的位置)即可使用Core Animation的動(dòng)畫效果。Core Animation將大部分實(shí)際的繪圖任務(wù)交給了圖形硬件來(lái)處理,圖形硬件會(huì)加速圖形渲染的速度。不會(huì)加重CPU的負(fù)擔(dān)而影響程序的運(yùn)行速度。(非常重要)因?yàn)橥媹D往往會(huì)加重CPU的負(fù)擔(dān),但如果交給GPU處理的話,無(wú)疑會(huì)很好的解決這個(gè)問(wèn)題,所以很推薦這個(gè)方法
Core Animation類的繼承關(guān)系圖

開發(fā)的常用屬性
duration : 動(dòng)畫的持續(xù)時(shí)間
beginTime : 動(dòng)畫的開始時(shí)間
repeatCount : 動(dòng)畫的重復(fù)次數(shù)
autoreverses : 執(zhí)行的動(dòng)畫按照原動(dòng)畫返回執(zhí)行
timingFunction : 控制動(dòng)畫的顯示節(jié)奏系統(tǒng)提供五種值選擇,分別是:
- kCAMediaTimingFunctionLinear 線性動(dòng)畫
- kCAMediaTimingFunctionEaseIn 先慢后快(慢進(jìn)快出)
- kCAMediaTimingFunctionEaseOut 先塊后慢(快進(jìn)慢出)
- kCAMediaTimingFunctionEaseInEaseOut 先慢后快再慢
- kCAMediaTimingFunctionDefault 默認(rèn),也屬于中間比較快
delegate : 動(dòng)畫代理。能夠檢測(cè)動(dòng)畫的執(zhí)行和結(jié)束。
代理執(zhí)行的開始和結(jié)束動(dòng)畫動(dòng)作:
(CAAnimationDelegate)
- (void)animationDidStart:(CAAnimation *)anim;
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
IOS動(dòng)畫的調(diào)用方式
- 第一種:UIView 代碼塊調(diào)用
- UIKit動(dòng)畫API使用起來(lái)十分簡(jiǎn)單與方便,他避免了Core Animation的復(fù)雜性,雖然事實(shí)上UIKit動(dòng)畫API的底層使用的也是Core Animation。(UIView的方法很多,這篇文章主要會(huì)介紹基礎(chǔ)的用法 Core Animation 這個(gè)簡(jiǎn)單舉個(gè)例子,UI View會(huì)在接下來(lái)的文章里詳細(xì)講述)
_demoView.frame = CGRectMake(0, SCREEN_HEIGHT/2-50, 50, 50);
[UIView animateWithDuration:1.0f animations:^{
_demoView.frame = CGRectMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50, 50, 50);
} completion:^(BOOL finished) {
_demoView.frame = CGRectMake(SCREEN_WIDTH/2-25, SCREEN_HEIGHT/2-50, 50, 50);
}];
- 第二種:使用Core Animation中的類
CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"position"];
anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-75)];
anima.toValue = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-75)];
anima.duration = 1.0f;
[_demoView.layer addAnimation:anima forKey:@"positionAnimation"];
基礎(chǔ)動(dòng)畫(CABaseAnimation)
CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"position"];
anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-75)];
anima.toValue = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-75)];
anima.duration = 1.0f;
//anima.fillMode = kCAFillModeForwards;
//anima.removedOnCompletion = NO;
[_demoView.layer addAnimation:anima forKey:@"positionAnimation"];
變換位移動(dòng)畫(CAKeyframeAnimation)
CAKeyframeAnimation和CABaseAnimation都屬于CAPropertyAnimatin的子類。CABaseAnimation只能從一個(gè)數(shù)值(fromValue)變換成另一個(gè)數(shù)值(toValue),而CAKeyframeAnimation則會(huì)使用一個(gè)NSArray保存一組關(guān)鍵幀。
CAKeyframeAnimation *anima1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)];
NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)];
NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)];
NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)];
NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)];
NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50)];
anima1.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];
[_demoView.layer addAnimation:anima forKey:@"pathAnimation"];
組和動(dòng)畫(CAAnimationGroup)
CAKeyframeAnimation *anima1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)];
NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)];
NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)];
NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)];
NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)];
NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50)];
anima1.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];
//縮放動(dòng)畫
CABasicAnimation *anima2 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
anima2.fromValue = [NSNumber numberWithFloat:0.8f];
anima2.toValue = [NSNumber numberWithFloat:2.0f];
//旋轉(zhuǎn)動(dòng)畫
CABasicAnimation *anima3 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
anima3.toValue = [NSNumber numberWithFloat:M_PI*4];
//組動(dòng)畫
CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
groupAnimation.animations = [NSArray arrayWithObjects:anima1,anima2,anima3, nil];
groupAnimation.duration = 4.0f;
[_demoView.layer addAnimation:groupAnimation forKey:@"groupAnimation"];
很好這些基礎(chǔ)的動(dòng)畫之后,我們就可以組裝一些比較復(fù)雜的動(dòng)畫了
但是接下來(lái)我要說(shuō)的就是一些和動(dòng)畫無(wú)關(guān),但是和我們有關(guān)的了,首先我要提一個(gè)問(wèn)題,如果運(yùn)行動(dòng)畫之后,我們對(duì)該動(dòng)畫的視圖進(jìn)行操作,那么我們操作的視圖位置,是視圖運(yùn)行動(dòng)畫之前的位置,還是視圖運(yùn)行動(dòng)畫之后的位置?
帶著這個(gè)疑問(wèn)我么講述下面的問(wèn)題
首先先講一個(gè)知識(shí)點(diǎn)
- Core Animation是直接作用在CALayer上的,并非UIView
CALayer與UIView的關(guān)系
在iOS中,你能看得見(jiàn)摸得著的東西基本上都是UIView,比如一個(gè)按鈕、一個(gè)文本標(biāo)簽、一個(gè)文本輸入框、一個(gè)圖標(biāo)等等,這些都是UIView。
其實(shí)UIView之所以能顯示在屏幕上,完全是因?yàn)樗鼉?nèi)部的一個(gè)圖層:
在創(chuàng)建UIView對(duì)象時(shí),UIView內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)圖層(即CALayer對(duì)象),通過(guò)UIView的layer屬性可以訪問(wèn)這個(gè)層。
@property(nonatomic,readonly,retain) CALayer *layer;
當(dāng)UIView需要顯示到屏幕上時(shí),會(huì)調(diào)用drawRect:方法進(jìn)行繪圖,并且會(huì)將所有內(nèi)容繪制在自己的圖層上,繪圖完畢后,系統(tǒng)會(huì)將圖層拷貝到屏幕上,于是就完成了UIView的顯示。
換句話說(shuō),UIView本身不具備顯示的功能,是它內(nèi)部的層才有顯示功能。
因此,通過(guò)調(diào)節(jié)CALayer對(duì)象,可以很方便的調(diào)整UIView的一些外觀屬性。
講到這里一些‘雞畜’比較好的同學(xué)可能就知道了,事件是作用于UIView層上的,而我們改變的是視圖上邊的CALayer,所以很自然的我們操作的視圖位置還是之前的位置。不過(guò)由這個(gè)問(wèn)題我們將會(huì)下篇文章將要講述的內(nèi)容,UIView與CAlayer的詳細(xì)講解。