UIView 動畫的兩種編程方式
2011-09-18 — UnmiiOS 中的 UIView 動畫編程其實還是很簡單的,像 CSS3 一樣,在給定的時間內完成狀態連續性的變化呈現。比如背景色,Frame 大小,位移、翻轉,特明度等。
以前我使用的編程方式都是用下面那樣的三段式處理:
1
2
3
4
5
6
7
8
|
[ UIView beginAnimations: nil context:
nil ]; [ UIView setAnimationDuration:1.0]; //要動畫改變的屬性 self .view.alpha
= 0.0; self .view.frame
= CGRectMake(10, 10, 50, 50); [ UIView commitAnimations]; |
那麼被 beginAnimations 和 commitAnimations 框起來的代碼就會讓你產生動畫效果,這種方式像是數據庫中的事物編程一樣。
還有另一種編程方式,使用代碼塊,對於常常書寫 JS 代碼的同志會比較適應,還是來個簡單的代碼片段:
1
2
3
4
5
|
[ UIView animateWithDuration:1.0 animations:^{ self .view.alpha
= 0.0; self .view.frame
= CGRectMake(10, 10, 50, 50); }]; |
對於不太複雜的動畫,上面的寫法很精練,因爲只有一條語句,如果動畫太過複雜了,寫在這樣一條語句中就會顯得冗長了,對於代碼調試沒那麼方便。
animateWithDuration 有三個重載方法:
-
animateWithDuration:animations:
-
animateWithDuration:animations:completion:
-
animateWithDuration:delay:options:animations:completion:
比如我們用最後面那個重載方法,可以比 beginAnimations...commitAnimations 更輕鬆的實現動畫完後執行的動作,如:
01
02
03
04
05
06
07
08
09
10
|
[ UIView animateWithDuration:1.0 delay:
0.0 options: UIViewAnimationOptionCurveEaseIn animations:^{ self .view.alpha
= 0.0; self .view.frame
= CGRectMake(10, 10, 50, 50); } completion:^( BOOL finished){ NSLog (@ "Do
something after the animation." ); }]; |
再回頭看看 beginAnimations...commitAnimations 該如何實現上面同樣的行爲:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
[ UIView beginAnimations: nil context:
nil ]; [ UIView setAnimationDuration:1.0]; [ UIView setAnimationDelay:0.0]; [ UIView setAnimationCurve: UIViewAnimationCurveEaseIn ]; [ UIView setAnimationDelegate: self ]; [ UIView setAnimationDidStopSelector: @selector (animationStopped)]; self .view.alpha
= 0.0; self .view.frame
= CGRectMake(10, 10, 50, 50); [ UIView commitAnimations]; |
還要給當前類加一個方法 animationStopped:
1
2
3
|
-( void )
animationStopped { NSLog (@ "Do
something after the animation." ); } |
代碼是多些,但是 beginAnimations...commitAnimations 編程方式是全能的,而 animateWithDuration 是有侷限性的,因爲它的目的就是讓編寫代碼更簡潔。在 animateWithDuration 中只提供了 completion 代碼塊,意即在動畫完成後執行的動作,而要達成
[UIView setAnimationWillStartSelector:@selector(animationWillStart)]
這樣的在動畫即將啓動之前的動作卻是無能爲力,還有些動畫設置也是 animateWithDuration 做不到。所以一旦你先前用 animateWithDuration 實現的動畫方式要增加稍複雜的功能而不得不用 beginAnimations...commitAnimations 來改寫時,付出就大了。
該用哪種方式,只能自己斟酌吧。