動畫基礎(chǔ)篇 之 animateWithDuration

轉(zhuǎn)自 :http://www.360doc.com/content/17/0518/15/43221886_655008916.shtml?

作者:Sindri的小巢

從登錄動畫說起

很長一段時間以來,我都在基于CALayer層進行動畫實現(xiàn),卻忽略了UIKit提供給我們的動畫接口。這些接口函數(shù)足夠的強大并且十分的靈活,足以滿足我們開發(fā)中大部分的動畫需求。

在我們了解這些強大的接口前,我們先來看看第一個效果:在用戶打開app要進行登錄的時候,賬戶和密碼輸入框從屏幕的左邊進入,接著登錄按鈕出現(xiàn)。

界面動畫

在這段動畫之中發(fā)生的最為明顯的事情就是兩個文本框的位置變化,在動畫開始之前,兩個文本框的位置應該是在屏幕的左邊,而下方的按鈕現(xiàn)在是隱藏狀態(tài)(設置alpha)

動畫開始前

因此,這個動畫之中發(fā)生的事情,我們可以用概括為下面的代碼:

self.userName.center.x?+=?offset;????//userName進入

self.password.center.x?+=?offset;????//password進入

self.login.alpha?=?1;????????????????//顯示登錄按鈕

既然已經(jīng)知道了我們的動畫發(fā)生了什么,接著就可以使用UIKit的動畫API讓我們的動畫活起來了


//設置文本框初始位置為屏幕左側(cè)

CGPoint?accountCenter?=?self.userName.center;

CGPoint?psdCenter?=?self.password.center;

accountCenter.x?-=?200;

pasCenter.x?-=?200;

self.userName.center?=?accountCenter;

self.password.center?=?psdCenter;

//還原中心坐標

accountCenter.x?+=?200;

psdCenter.x?+=?200;

[UIView?animateWithDuration:?0.5?animations:?^{

self.userName.center?=?accountCenter;

self.password.center?=?passwordCenter;

self.login.alpha?=?1;

}?completion:?nil];

在UIKit中,系統(tǒng)提供了animate標題打頭的屬于UIView的類方法讓我們可以輕松的制作動畫效果,每一個這樣的類方法提供了名為animations的block代碼塊,這些代碼會在方法調(diào)用后立刻或者延遲一段時間以動畫的方式執(zhí)行。此外,所有這些API的第一個參數(shù)都是用來設置動畫時長的。

在viewDidAppear:中運行這段代碼,你會看到文本框從左側(cè)滑動,按鈕也漸變顯示出來的,但是跟我們要的結(jié)果不太一樣 —— 三個動畫沒有錯開,效果并不那么的好看。我們希望密碼框能在賬戶文本框滑動后的一段時間后再出現(xiàn),按鈕同樣也需要晚一些顯示。所以,我們需要使用下面的方法來實現(xiàn)這個效果:

[UIView?animateWithDuration:?0.5?delay:?0.35?options:?UIViewAnimationOptionCurveEaseInOut?animations:?^{

self.password.center?=?passwordCenter;

}?completion:?^(BOOL?finished)?{

[UIView?animateWithDuration:?0.2?animations:?^{

self.login.alpha?=?1;

}];

}];

這個方法看起來非常的熟悉,相比上面的方法這里多了幾個參數(shù)來高度定制我們的動畫:

duration: ?動畫時長

delay: ?決定了動畫在延遲多久之后執(zhí)行

options:用來決定動畫的展示方式,接下來會進行講解

animations:轉(zhuǎn)化成動畫表示的代碼

completion:動畫結(jié)束后執(zhí)行的代碼塊

在上面的代碼中,密碼輸入框在延后0.35秒之后開始從左側(cè)出來,在持續(xù)0.5秒的動畫之后,開始漸變顯示按鈕,然后動畫完成。

可實現(xiàn)動畫的屬性

現(xiàn)在你已經(jīng)可以制作簡單的動畫了,但要記?。翰皇撬行薷膶傩缘牟僮鞣诺絘nimations代碼塊中都是變成動畫實現(xiàn)的 —— 不管你怎么修改一個視圖的tag,或者是delegate。因此,可實現(xiàn)動畫的屬性必定會導致視圖的重新渲染。

這些可以生成動畫的屬性大致可以分成這么三類:坐標尺寸、視圖顯示、形態(tài)變化

坐標尺寸類

bounds:修改這個屬性會結(jié)合center屬性重新計算frame。建議通過這個屬性修改尺寸

frame:修改這個屬性通常會導致視圖形變的同時也發(fā)生移動,然后會重新設置center跟bounds屬性

center: 設置后視圖會移動到一個新位置,修改后會結(jié)合bounds重新計算frame

尺寸修改

視圖顯示類

backgroundColor: 修改這個屬性會產(chǎn)生顏色漸變過渡的效果,本質(zhì)上是系統(tǒng)不斷修改了tintColor來實現(xiàn)的

alpha:修改這個屬性會產(chǎn)生淡入淡出的效果

hidden:修改這個屬性可以制作翻頁隱藏的效果

修改透明度

形態(tài)變化類

transform:修改這個屬性可以實現(xiàn)旋轉(zhuǎn)、形變、移動、翻轉(zhuǎn)等動畫效果,其通過矩陣運算的方式來實現(xiàn),因此更加強大

旋轉(zhuǎn)

動畫參數(shù)

上面我們使用到的動畫方法中有一個重要的參數(shù)options,它能讓你高度的自定義動畫效果。下面展示這個參數(shù)類型的值集合,你可以通過結(jié)合不同的參數(shù)來實現(xiàn)自己的動畫:

Repeating

1

2UIViewAnimationOptionRepeat//動畫循環(huán)執(zhí)行

UIViewAnimationOptionAutoreverse//動畫在執(zhí)行完畢后會反方向再執(zhí)行一次

我們將這兩個參數(shù)傳入到上面密碼框出現(xiàn)動畫中,看看會有什么效果(不同的參數(shù)使用|操作符一起傳入)

[UIView?animateWithDuration:?0.5?delay:?0.35?options:?UIViewAnimationOptionAutoreverse?|?UIViewAnimationOptionRepeat?animations:?^{

self.password.center?=?passwordCenter;

}?completion:?^(BOOL?finished)?{

[UIView?animateWithDuration:?0.2?animations:?^{

self.login.alpha?=?1;

}];

}];

重復的動畫

我們可以看到密碼框在不斷的循環(huán)進入屏幕,反方向退出屏幕這個操作,并且登錄按鈕也始終沒有漸變出現(xiàn)。由此可以知道UIViewAnimationOptionRepeat參數(shù)不僅是讓動畫循環(huán)播放,并且還導致了completion的回調(diào)永遠無法執(zhí)行。

Easing

我們都知道,一個好的動畫應該更符合我們認知的規(guī)則。比如,任何事物都不能突然間的開始移動和停下,像車輛啟動和停止都有一個加速和減速的過程。

汽車的加速減速.png

為了讓動畫更具符合我們的認知,系統(tǒng)同樣提供了類似的效果的參數(shù)給我們使用:

UIViewAnimationOptionCurveEaseInOut//先加速后減速,默認

UIViewAnimationOptionCurveEaseIn//由慢到快

UIViewAnimationOptionCurveEaseOut//由快到慢

UIViewAnimationOptionCurveLinear//勻速

我在demo上創(chuàng)建了四個橙色的UIView,分別傳入這四個不同的參數(shù),然后讓這四個view在同一時間y軸上向上移動。

[self?animatedView:?_view1];

[self?animatedView:?_view2];

[self?animatedView:?_view3];

[self?animatedView:?_view4];

//y軸上移動視圖上升250

-?(void)animatedView:?(UIView?*)view

{

[UIView?animateWithDuration:?0.5?delay:?0?options:?UIViewAnimationOptionCurveLinear?animations:?^{

CGPoint?center?=?view.center;

center.y?-=?250;

view.center?=?center;

}?completion:?nil];

}

四種線性速度表示

在模擬器運行狀態(tài)下,點擊上面的菜單欄DEBUG -> Slow Animation或者快捷鍵command + T,這會放慢我們app的動畫運行速度(demo在6p的模擬器上運行)。

在減速環(huán)境下,我們看到四個view的速度變化如下:

1、逐漸加速。EaseIn

2、先加速,后減速。EaseInOut

3、速度領(lǐng)先,然后減速。EaseOut

4、勻速運動。Linear

運行最開始的登錄動畫,放慢模擬器的動畫速度,你會看到默認情況下使用的EaseInOut參數(shù)使得密碼框在接近結(jié)束點的時候出現(xiàn)了明顯的減速動畫。

Transitioning

除了上面提到的這些效果,在視圖、圖片切換的時候,我們還能通過傳入下面的這些參數(shù)來實現(xiàn)一些特殊的動畫效果。

UIViewAnimationOptionTransitionNone//沒有效果,默認

UIViewAnimationOptionTransitionFlipFromLeft//從左翻轉(zhuǎn)效果

UIViewAnimationOptionTransitionFlipFromRight//從右翻轉(zhuǎn)效果

UIViewAnimationOptionTransitionCurlUp//從上往下翻頁

UIViewAnimationOptionTransitionCurlDown//從下往上翻頁

UIViewAnimationOptionTransitionCrossDissolve//舊視圖溶解過渡到下一個視圖

UIViewAnimationOptionTransitionFlipFromTop//從上翻轉(zhuǎn)效果

UIViewAnimationOptionTransitionFlipFromBottom//從上翻轉(zhuǎn)效果

那么這些參數(shù)使用的時機是什么時候呢?我們來看看這么一段代碼:

[UIView?transitionWithView:?firstPV?duration:?0.5?options:?UIViewAnimationOptionTransitionFlipFromLeft?animations:?^{

[firstPV?flipCard];

}?completion:?^(BOOL?finished)?{

isAnimating?=?NO;

}];

-?(void)flipCard

{

if(isfliped)?{

self.image?=?[UIImage?imageNamed:?@"flipPicBG.png"];

isfliped?=?NO;

}else{

self.image?=?[UIImage?imageNamed:?[NSString?stringWithFormat:?@"flipPic%d.png",?type]];

isfliped?=?YES;

}

}

這段代碼中我改變了一個UIImageView的圖片顯示,同樣用了一個動畫的方式表現(xiàn)。這里用到了一個新的動畫API方法,transitionWithView: duration: options: animations: completion:,這個方法跟上面的animateWithDuration系列方法相比多了一個UIView類型的參數(shù),這個參數(shù)接收的對象作為動畫的作用者。這段代碼是我以前做的一個翻卡匹配的小游戲,點擊之后的動畫效果如下:

翻卡匹配小游戲

在模擬器下使用command+T放慢了動畫的速度之后,我截取了翻轉(zhuǎn)的四張圖片:

慢動作翻轉(zhuǎn)

在我們切換圖片的時候,原有的圖片會基于視圖中心位置進行x軸上的翻轉(zhuǎn),為了達到更逼真的效果,系統(tǒng)還為我們在切換中加上了陰影效果(ps: 再次要說明的是,transition的動畫你應該只用在視圖的切換當中 —— 你不會在移動中產(chǎn)生任何transition效果的)

彈簧動畫

恭喜你,你已經(jīng)可以使用UIKit的動畫接口制作精美的動畫了,通過組合不同的options參數(shù)你可以制作真實的動畫。但是,我們總是能做的更多,比如一個彈簧被用力壓扁,當松開手的時候會反復彈動。使用上面的方式縱然可以實現(xiàn)這樣的動畫,但代碼量復雜,也基本無復用性可言,可想而知會是糟糕的代碼。因此,我們需要其他的動畫方式,系統(tǒng)也正好提供了這樣的一種動畫供我們使用:

1

+?(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

照例科普一下額外的參數(shù)信息:

dampingRatio:速度衰減比例。取值范圍0 ~ 1,值越低震動越強

velocity:初始化速度,值越高則物品的速度越快

當一個圓角按鈕高速移動的進入界面中,接著狠狠的震動,這絕對會狠狠地吸引住你的眼球。比如我嘗試著讓某個UICollectionView的分類按鈕從屏幕下方彈入視圖的時候;又或者我讓這個小球彈到右下角,以提示用戶該如何操作:

小球彈出效果

這效果非常的棒,在看到這些小圓球之后,你本能的會想要去點擊這些按鈕,而這些小球彈出的動畫僅僅需要下面這么幾句代碼:

CGPoint?center?=?cell.center;

CGPoint?startCenter?=?center;

startCenter.y?+=?LXD_SCREEN_HEIGHT;

cell.center?=?startCenter;

[UIView?animateWithDuration:?0.5?delay:?0.35?*?indexPath.item?usingSpringWithDamping:?0.6?initialSpringVelocity:?0?options:?UIViewAnimationOptionCurveLinear?animations:?^{

cell.center?=?center;

}?completion:?nil];

除了這段彈出的代碼,在小球被點擊的時候,還會產(chǎn)生一個彈到右下角的動畫,然后從左側(cè)彈出列表。這非常的酷,因為不用額外的提示,用戶會很自然的知道該怎么回到分組的界面 —— 點擊一下右下角的圓形按鈕。這是非常重要的,我們的動畫應該不僅僅只是為了讓界面更加的優(yōu)雅漂亮,還應該能用以減少用戶學習使用app的成本,這些都是動畫的追求。

最后

相比起PC端的粗糙,移動端的應用需要更加精致,精致復雜的動畫都是源于一個個簡單的動畫組合而成的。本文作為動畫篇的第一篇博客,目的是為了從最簡單的UIView動畫講起,慢慢的拓展其它的動畫,也希望能起到拋磚引玉的作用。在文章的最后,如果你是iOS動畫的初學者,請嘗試結(jié)合上面提到的知識,為本文最開始的登錄demo中添加代碼,讓按鈕從下方漸變顯示彈出:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容