IOS之動畫
15.1 動畫介紹
在iOS中動畫實現技術主要是:Core Animation。 Core Animation負責所有的滾動、旋轉、縮小和放大以及所有的iOS動畫效果。其中UIKit類通常都有animated:引數部分,它可以允許是否使用動畫。
Core Animation還與Quartz緊密結合在一起,每個UIView都關聯到一個CALayer物件,CALayer是Core Animation中的圖層。
15.2 Core Animation基礎
Core Animation建立動畫時候會修改CALayer屬性,然後讓這些屬性流暢地變化。Core Animation相關知識點:
圖層,圖層是動畫發生的地方,CALayer總是與UIView關聯,通過layer屬性訪問。
隱式動畫,這是一種最簡單的動畫,不用設定定時器,不用考慮執行緒或者重畫。
顯式動畫,是一種使用CABasicAnimation建立的動畫,通過CABasicAnimation,可以更明確地定義屬性如何改變動 畫。
關鍵幀動畫,這是一種更復雜的顯式動畫型別,這裡可以定義動畫的起點和終點,還可以定義某些幀之間的動畫。
15.3 隱式動畫
例項ianimate:
#import <UIKit/UIKit.h> #import <QuartzCore/QuartzCore.h> @interfaceianimateViewController : UIViewController { IBOutlet UIImageView *plane; } -(IBAction)movePlane:(id)sender; @end //--m -(IBAction)movePlane:(id)sender { [UIView beginAnimations:nil context:NULL]; CGAffineTransform moveTransform = CGAffineTransformMakeTranslation(180, 200); plane.layer.affineTransform=moveTransform; plane.layer.opacity = 1; [UIView commitAnimations]; }
飛機圖片的不透明度(opacity)初始為0.25,然後在動畫過程中不透明度設定為1.0。這個過程是設定飛機圖片物件的層屬性的,plane.layer.opacity = 1;
[plane.layer setAffineTransform:moveTransform];設定飛機圖片層物件的仿射移動變換。
15.4 顯式動畫
eanimate關鍵程式碼:
#import <UIKit/UIKit.h> #import <QuartzCore/QuartzCore.h> @interface eanimateViewController : UIViewController { IBOutlet UIImageView *plane; } -(IBAction)movePlane:(id)sender; @end //--m -(IBAction)movePlane:(id)sender { CABasicAnimation *opAnim = [CABasicAnimation animationWithKeyPath:@"opacity"]; opAnim.duration = 3.0; opAnim.fromValue = [NSNumber numberWithFloat:.25]; opAnim.toValue= [NSNumber numberWithFloat:1.0]; opAnim.cumulative = YES; opAnim.repeatCount = 2; [plane.layer addAnimation:opAnim forKey:@"animateOpacity"]; CGAffineTransform moveTransform = CGAffineTransformMakeTranslation(180, 200); CABasicAnimation *moveAnim = [CABasicAnimation animationWithKeyPath:@"transform"]; moveAnim.duration = 6.0; moveAnim.toValue= [NSValue valueWithCATransform3D: CATransform3DMakeAffineTransform(moveTransform)]; [plane.layer addAnimation:moveAnim forKey:@"animateTransform"]; }
顯式動畫時候,不必定義CALayer的變化,也不必執行它們,而是通過CABasicAnimation逐個定義動畫。其中每個動畫都含有各自的duration、repeatCount等屬性。然後,使用addAnimation:forKey:方法分別將每個動畫應用到層中。
[CABasicAnimation animationWithKeyPath:@“opacity”]獲得透明度動畫物件,@“transform”是指定轉換動畫。
opAnim.cumulative 屬性是指定累計
opAnim.repeatCount 重複執行次數
CATransform3DMakeAffineTransform函式是將仿射變換矩陣變成Core Animation使用的Transform3D型別的矩陣。
15.5 關鍵幀顯式動畫
eanimate_keyFrame關鍵程式碼:
#import <UIKit/UIKit.h> #import <QuartzCore/QuartzCore.h> @interface eanimateViewController : UIViewController { IBOutlet UIImageView *plane; } -(IBAction)movePlane:(id)sender; @end //-m -(IBAction)movePlane:(id)sender { CAKeyframeAnimation *opAnim = [CAKeyframeAnimation animationWithKeyPath:@"opacity"]; opAnim.duration = 6.0; opAnim.values =[NSArray arrayWithObjects: [NSNumber numberWithFloat:0.25], [NSNumber numberWithFloat:0.75], [NSNumber numberWithFloat:1.0], nil]; opAnim.keyTimes = [NSArray arrayWithObjects: [NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:0.5], [NSNumber numberWithFloat:1.0], nil]; [plane.layer addAnimation:opAnim forKey:@"animateOpacity"]; CGAffineTransform moveTransform = CGAffineTransformMakeTranslation(180, 200); CABasicAnimation *moveAnim = [CABasicAnimation animationWithKeyPath:@"transform"]; moveAnim.duration = 6.0; moveAnim.toValue= [NSValue valueWithCATransform3D: CATransform3DMakeAffineTransform(moveTransform)]; [plane.layer addAnimation:moveAnim forKey:@"animateTransform"]; }
animation.values是一個值的陣列。
animation.keyTimes是一個每個幀片段持續的時間比例,取值範圍0.0-1.0之間。
關鍵幀之路徑例項BallSteps
#import <UIKit/UIKit.h> #import <QuartzCore/CoreAnimation.h> @interface BallStepsViewController : UIViewController { UIButton *drawButton; UIImageView *imageView; } @property (nonatomic, retain) IBOutlet UIButton *drawButton; @property (nonatomic, retain) IBOutlet UIImageView *imageView; - (IBAction)drawStar:(id)sender; @end //--m #import "BallStepsViewController.h" @implementation BallStepsViewController @synthesize drawButton; @synthesize imageView; - (IBAction)drawStar:(id)sender { [drawButton setEnabled:NO]; CGMutablePathRef starPath = CGPathCreateMutable(); CGPathMoveToPoint(starPath,NULL,160.0f, 100.0f); CGPathAddLineToPoint(starPath, NULL, 100.0f, 280.0f); CGPathAddLineToPoint(starPath, NULL, 260.0, 170.0); CGPathAddLineToPoint(starPath, NULL, 60.0, 170.0); CGPathAddLineToPoint(starPath, NULL, 220.0, 280.0); CGPathCloseSubpath(starPath); CAKeyframeAnimation *animation = nil; animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; [animation setDuration:10.0f]; [animation setDelegate:self]; [animation setPath:starPath]; CFRelease(starPath); starPath = nil; [[imageView layer] addAnimation:animation forKey:@"position"]; } - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag { [drawButton setEnabled:YES]; } - (void)dealloc { [drawButton release]; [imageView release]; [super dealloc]; } @end
[CAKeyframeAnimation animationWithKeyPath:@“position”];建立一個position型別的關鍵幀動畫。
關鍵幀動畫中可以定義路徑,把這些路徑放入到CGMutablePathRef 中與CG中的很相似。
CGPathCloseSubpath(starPath);結束路徑。
[animation setPath:starPath];設定路徑。
[animation setDelegate:self];設定委託物件為本身,即回撥方法 animationDidStop:finished:。
最後CFRelease(starPath);釋放路徑。
15.6 UIView級別動畫
除了直接使用Core Animation 層實現動畫,我們還有UIView直接實現隱式動畫。
例項ViewAnimation:
@interface MainViewController : UIViewController { UIImageView *animImageView; UIButton *button; } @property (assign) IBOutlet UIImageView *animImageView; @property (assign) IBOutlet UIButton *button; - (IBAction)action:(id)sender; @end
//--m #import "MainViewController.h" @implementation MainViewController @synthesize animImageView; @synthesize button; - (IBAction)action:(id)sender { [UIView beginAnimations:@"Hide Button" context:nil]; [[self button] setAlpha:0.0]; [UIView commitAnimations]; [UIView beginAnimations:@"Slide Around" context:nil]; [UIView setAnimationDuration:1.0]; [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(viewAnimationDone:)]; [UIView setAnimationRepeatCount:3]; [UIView setAnimationRepeatAutoreverses:YES]; CGPoint center = [[self animImageView] center]; center.y += 100; [[self animImageView] setCenter:center]; [UIView commitAnimations]; } - (void)viewAnimationDone:(NSString*)name { [UIView beginAnimations:@"Show Button" context:nil]; [[self button] setAlpha:1.0]; [UIView commitAnimations]; } @end
UIView中的動畫是在動畫塊中定義的,動畫塊是UIView beginAnimations:context:開始, 在UIView commitAnimations結束。
首先開始將按鈕設定透明度為0的,結果是開始動畫時候隱藏了。
然後,又開始新的動畫中設定委託事件:
[UIView setAnimationDelegate:self]
[UIView setAnimationDidStopSelector:@selector(viewAnimationDone:)];
當動畫結束的時候呼叫viewAnimationDone:方法。
內建UIView動畫
UIView具有一個UIViewAnimationTransition屬性可以設定動畫,這些動畫是iOS提供幾個常用動畫有:
UIViewAnimationTransitionNone
UIViewAnimationTransitionFlipFromLeft
UIViewAnimationTransitionFlipFromRight
UIViewAnimationTransitionCurlUp
UIViewAnimationTransitionCurlDown
例項UIViewAnimation
#import <UIKit/UIKit.h> @interface UIViewAnimationViewController : UIViewController { } - (IBAction)doUIViewAnimation:(id)sender; @end //-m #import "UIViewAnimationViewController.h" @implementation UIViewAnimationViewController - (IBAction)doUIViewAnimation:(id)sender{ [UIView beginAnimations:@"animationID" context:nil]; [UIView setAnimationDuration:1.5f]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; [UIView setAnimationRepeatAutoreverses:NO]; UIButton *theButton = (UIButton *)sender; switch (theButton.tag) { case 1: [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES];//oglFlip, fromLeft break; case 2: [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];//oglFlip, fromRight break; case 3: [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES]; break; case 4: [UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view cache:YES]; break; default: break; } //[self.view exchangeSubviewAtIndex:1 withSubviewAtIndex:0]; [UIView commitAnimations]; } - (void)viewDidUnload { // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)dealloc { [super dealloc]; } @end
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]設定動畫曲線,動畫曲線指定的是動畫進入和退出的方式,它也有幾個常量:
UIViewAnimationCurveEaseInOut
UIViewAnimationCurveEaseIn
UIViewAnimationCurveEaseOut
UIViewAnimationCurveLinear
setAnimationTransition: forView: cache:方法第一個引數定義動畫型別,第二個引數是當前檢視物件,第三個引數上使用緩衝區。