咱們看到不少App帶有絢麗狂拽的特效,別出心裁的控件設計,很大程度上提升了用戶體驗,在增長了實用性的同時,也賦予了app無限的生命力。這些華麗的效果不少都是基於iOS的核心動畫原理實現的,本文介紹一些iOS開發中最基本的動畫效果實現,掌握了基本屬性,才能夠繪製出更華麗的效果。設計模式
1、概念擴充數組
一、核心動畫:緩存
Core Animation,它是一組很是強大的動畫處理API,使用它能作出很是炫麗的動畫效果,並且每每是事半功倍。 Core Animation能夠用在Mac OS X和iOS平臺。在iOS平臺中,動畫效果會略少一些。另外,iOS開發中實現動畫的方式也不僅是核心動畫一種,後面會介紹UIView的幾種動畫。併發
二、執行和建立動畫過程:app
(1)Core Animation的動畫執行過程都是在後臺操做的,不會阻塞主線程。要注意的是,Core Animation是直接做用在CALayer上的,並不是UIView。因此,CALayer是核心動畫的基礎。框架
(2)關於框架:iOS7之後,再也不須要導入QuartzCore.framework框架和主頭文件<QuartzCore/QuartzCore.h>函數
(3)基本的建立動畫流程性能
三、動畫類型:後面作詳細的使用介紹測試
四、本質與繼承關係:動畫
(1)本質:在後臺移動圖層中的內容, 執行完畢後圖層自己的位置並無發生變化。
(2)全部的動畫都繼承自CAAnimation
2、CAAnimation
一、定義:
全部動畫對象的父類,負責控制動畫的持續時間和速度,是個抽象類,不能直接使用,應該使用它具體的子類。
二、 屬性解析:(不少屬性都是來自CAMediaTiming協議)
三、隱式代理:delegate
(1) CAAnimation有一個id類型的delegate屬性,可是此屬性沒有遵照任何協議,自己也沒有任何代理協議。
(2) 實現代理方法:注意,這裏的兩個方法,是在NSObject擴展中聲明的,因此是自己就是NSObject的方法,每個類都能實現該方法。o(╯□╰)o。。
(3)給CAAnimation的delegate賦值(說明誰來代理)、重寫代理方法,就能夠實現「隱式」代理。
3、CAPropertyAnimation
一、定義:
是CAAnimation的子類,也是個抽象類,要想建立動畫對象,應該使用它的兩個子類:CABasicAnimation和CAKeyframeAnimation。
二、屬性解析:
(1)圖1:position屬性———CGPoint類型
(2)圖2:frame和bounds屬性 ———CGRect類型
(3)圖3:transform屬性 ————CATransform3D 類型
4、CABasicAnimation 基本動畫
一、定義:
基本動畫,CAPropertyAnimation的子類。經過設置keyPath,兩個值之間的變化實現動畫。
二、屬性解析:
隨着動畫的進行,在長度爲duration的持續時間內,keyPath相應屬性的值從fromValue漸漸地變爲toValue,若是fillMode=kCAFillModeForwards和removedOnComletion=NO,那麼在動畫執行完畢後,圖層會保持顯示動畫執行後的狀態。但在實質上,圖層的屬性值仍是動畫執行前的初始值,並無真正被改變。好比,CALayer的position初始值爲(0,0),CABasicAnimation的fromValue爲(10,10),toValue爲(100,100),雖然動畫執行完畢後圖層保持在(100,100)這個位置,實質上圖層的position仍是爲(0,0)
三、代碼案例:
給出一個基本動畫和關鍵幀動畫的基本配置案例
效果:
#pragma mark - 基本動畫:按路徑移動(默認返回原位) - (IBAction)moveAtPathBack:(UIButton *)sender { //設置keyPath 爲:transform.translation.x CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"]; //起始值 animation.fromValue= @(150); //到達值 animation.toValue = @(-150); animation.duration=1; //要添加到layer [self.button.layer addAnimation:animation forKey:nil]; } #pragma mark - 基本動畫:按路徑移動(不返回原位) - (IBAction)moveAtPath:(id)sender { //設置keyPath 爲:transform.translation.x CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"]; animation.fromValue= @(150); animation.toValue = @(-150); animation.duration=1; //不回到原位置,可是控件的「真身」還在原位 animation.removedOnCompletion=NO; //保持的狀態 animation.fillMode=kCAFillModeForwards; [self.button.layer addAnimation:animation forKey:nil]; } #pragma mark - 基本動畫:旋轉 - (IBAction)rotate:(UIButton *)sender { //設置keyPath 爲:transform.rotation.y CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"]; //轉一週 NSNumber * num = @(M_PI*2); animation.toValue=num; animation.removedOnCompletion=NO; animation.fillMode=kCAFillModeForwards; //轉了3秒 animation.duration=3; //重複次數無限大 animation.repeatCount=CGFLOAT_MAX; [self.button.layer addAnimation:animation forKey:nil]; }
5、CAKeyframeAnimation 關鍵幀動畫
一、定義:
關鍵幀動畫,也是CApropertyAnimation的子類。經過設置keyPath,多個值之間的變化實現動畫。
二、屬性解析:
三、 與CABasicAnimation的區別:
四、代碼案例
#pragma mark - 關鍵幀:按方形路徑移動 - (IBAction)keyPathPath:(UIButton *)sender { //設置keyPath 爲:position CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; //設置5個值 NSValue * v1 = [NSValue valueWithCGPoint:CGPointMake(100, 200)]; NSValue * v2 = [NSValue valueWithCGPoint:CGPointMake(100, 400)]; NSValue * v3 =[NSValue valueWithCGPoint:CGPointMake(300, 400)]; NSValue * v4 = [NSValue valueWithCGPoint:CGPointMake(300, 200)]; NSValue * v5 = [NSValue valueWithCGPoint:CGPointMake(100, 200)]; //加入「值」數組 animation.values=@[v1,v2,v3,v4,v5]; animation.duration=2; animation.repeatCount=CGFLOAT_MAX; animation.removedOnCompletion=NO; animation.fillMode=kCAFillModeForwards; [self.button.layer addAnimation:animation forKey:nil]; } #pragma mark - 關鍵幀:size變化 - (IBAction)keyPathSize:(id)sender { //設置keyPath 爲:bounds.size CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"bounds.size"]; //設置三個值 NSValue * v0 = [NSValue valueWithCGSize:CGSizeMake(100, 100)]; NSValue * v1 = [NSValue valueWithCGSize:CGSizeMake(200, 200)]; NSValue * v2 = [NSValue valueWithCGSize:CGSizeMake(100, 100)]; animation.values=@[v0,v1,v2]; animation.duration=0.5; animation.repeatCount=CGFLOAT_MAX; animation.removedOnCompletion=NO; animation.fillMode=kCAFillModeForwards; [self.button.layer addAnimation:animation forKey:nil]; } #pragma mark - 關鍵幀:抖動 - (IBAction)keyPathShake:(id)sender { //設置keyPath 爲:transform.rotation.z CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; //設置兩個角度值 NSNumber * n1 = @(-M_PI_4/3); NSNumber * n2 = @(M_PI_4/3); //再三個值之間進行改變 animation.values=@[n1,n2,n1,]; animation.repeatCount=CGFLOAT_MAX; animation.duration=0.15; animation.removedOnCompletion=NO; animation.fillMode=kCAFillModeForwards; [self.button.layer addAnimation:animation forKey:nil]; }
6、CAAnimationGroup 組動畫
一、定義:
二、屬性解析:
三、代碼案例
給出一個組動畫和轉場動畫的基本配置案例
效果:
#pragma mark - 組動畫 - (IBAction)groupAnimation:(UIButton *)sender { [self makeView:nil]; //動畫1:移動 CAKeyframeAnimation * animation1 = [CAKeyframeAnimation animationWithKeyPath:@"position"]; NSValue * v1 = [NSValue valueWithCGPoint:CGPointMake(100, 200)]; NSValue * v2 = [NSValue valueWithCGPoint:CGPointMake(100, 400)]; NSValue * v3 = [NSValue valueWithCGPoint:CGPointMake(300, 400)]; NSValue * v4 = [NSValue valueWithCGPoint:CGPointMake(300, 200)]; NSValue * v5 = [NSValue valueWithCGPoint:CGPointMake(100, 200)]; animation1.values=@[v1,v2,v3,v4,v5]; animation1.repeatCount=CGFLOAT_MAX; animation1.removedOnCompletion=NO; animation1.fillMode=kCAFillModeForwards; //動畫2 : CAKeyframeAnimation * animation2 = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; NSNumber * n1 = @(-M_PI_4/2); NSNumber * n2 = @(M_PI_4/2); animation2.values=@[n1,n2,n1,]; animation2.repeatCount=CGFLOAT_MAX; animation2.duration=0.15; animation2.removedOnCompletion=NO; animation2.fillMode=kCAFillModeForwards; //建立組動畫 CAAnimationGroup * animation = [CAAnimationGroup animation]; animation.animations=@[animation1,animation2]; animation.duration=2; animation.repeatCount=CGFLOAT_MAX; //將組動畫加入到layer就能夠了,各個動畫併發執行 [self.button.layer addAnimation:animation forKey:nil]; }
7、CATransition 轉場動畫
一、定義:
轉場動畫,CAAnimation的子類,用於作頁面跳轉時的轉場動畫,可以爲層提供移出屏幕和移入屏幕的動畫效果。UINavigationController就是經過CATransition實現了將控制器的視圖推入屏幕的動畫效果。這些動畫的效果系統已經寫好,咱們只要配置一些屬性便可。
二、屬性解析:
三、代碼案例(這裏把下面的UIView動畫一塊兒實現,方便比較)
#pragma mark - 轉場動畫 -(void)makeImage { //生成一個測試轉場動畫的視圖 UIImageView * imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"1"]]; imageView.center =self.view.center; self.imageView=imageView; [self.view addSubview: imageView]; //建立手勢識別器,用來響應屏幕滑動 UISwipeGestureRecognizer * swipeLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeImage:)]; UISwipeGestureRecognizer * swipeRight =[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeImage:)]; //添加識別器屬性 swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft; swipeRight.direction = UISwipeGestureRecognizerDirectionRight; //添加到視圖 [self.view addGestureRecognizer:swipeLeft]; [self.view addGestureRecognizer:swipeRight]; } #pragma mark - 滑動屏幕響應事件 -(void)swipeImage:(UISwipeGestureRecognizer *)rec { //判斷滑動方向 //向左滑動 if (rec.direction==UISwipeGestureRecognizerDirectionLeft) { self.index++; //圖片能夠循環播放 if (self.index==6) { self.index=1; } } //向右滑動 else{ self.index--; if (self.index==0) { self.index=5; } } #pragma mark - 方式一,使用過CATransition實現轉場(漸變消失) //這裏的changeStyle只是點擊按鈕的判斷 if (self.changeStyle==1) { //建立動畫 CATransition * animation = [CATransition animation]; //前一張消失 animation.type = kCATransitionFade; //將動畫添加到控件layer,控件屬性變化時(圖片更換)將採用設定動畫 [self.imageView.layer addAnimation:animation forKey:nil]; } #pragma mark - 方式二 ,使用UIView(block)實現轉場(向左拖:左右旋轉+ 向右拖:上下翻頁) else if(self.changeStyle==2) { //若是向左滑動,向左旋轉顯示 if (rec.direction==UISwipeGestureRecognizerDirectionLeft) { [UIView transitionWithView:self.imageView duration:1 options:UIViewAnimationOptionTransitionFlipFromRight animations:^{ //block裏面是控件的屬性變化,這裏和CATransition實現不一樣 UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",self.index]]; self.imageView.image=image; } completion:nil]; } //若是向右滑動,子頁面向下推出 else{ [UIView transitionWithView:self.imageView duration:1 options:UIViewAnimationOptionTransitionCurlUp animations:^{ UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",self.index]]; self.imageView.image=image; } completion:nil]; } } #pragma mark - 方式三,使用過CATransition實現轉場(向左滑:向左退出 + 向右滑:向下推出) else{ CATransition * animation = [CATransition animation]; //若是向右滑動,子頁面從左推出 if (rec.direction == UISwipeGestureRecognizerDirectionRight) { animation.subtype = kCATransitionFromBottom; } //若是向右滑動,子頁面從下推出 else{ animation.subtype = kCATransitionFromRight; } animation.type = kCATransitionPush; [self.imageView.layer addAnimation:animation forKey:nil]; } UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",self.index]]; //這是添加了動畫的控件,屬性改變時按照咱們設定的有動畫效果 self.imageView.image=image; }
8、UIView block動畫———(也可實現轉場動畫)
一、定義:
UIKit框架直接將動畫集成到UIView類中,當內部的一些屬性發生改變時,UIView將爲這些改變提供動畫支持。
二、UIView動畫的幾種類別:
(1)三種block方式實現:所謂block方式,就是將改變視圖屬性的代碼寫在block中,實現動畫
參數解析:
duration: 動畫的持續時間
delay: 動畫延遲delay秒後開始
options: 動畫的節奏控制
animations: 將改變視圖屬性的代碼放在這個block中
completion: 動畫結束後,會自動調用這個block
參數解析:
duration: 動畫的持續時間
view: 須要進行轉場動畫的視圖
options: 轉場動畫的類型
animations: 將改變視圖屬性的代碼放在這個block中
completion: 動畫結束後,會自動調用這個block
方法調用完畢後,至關於執行了下面兩句代碼:
// 添加toView到父視圖
[fromView.superview addSubview:toView];
// 把fromView從父視圖中移除
[fromView.superview removeFromSuperview];
參數解析:
duration: 動畫的持續時間
options: 轉場動畫的類型
animations: 將改變視圖屬性的代碼放在這個block中
completion: 動畫結束後,會自動調用這個block
(2)首尾式動畫等(下文單獨介紹)。
9、UIView 首尾式動畫
一、定義:
UIView的另外一種實現動畫方式。
二、執行方式:
執行動畫所須要的工做由UIView類自動完成,但仍要在但願執行動畫時通知視圖,爲此須要將改變屬性的代碼放在[UIView beginAnimations:nil context:nil]和[UIView commitAnimations]之間,俗稱首尾式動畫。
三、常見方法解析:
設置動畫代理對象,當動畫開始或者結束時會發消息給代理對象
當動畫即將開始時,執行delegate對象的selector,而且把beginAnimations:context:中傳入的參數傳進selector
當動畫結束時,執行delegate對象的selector,而且把beginAnimations:context:中傳入的參數傳進selector
動畫的持續時間,秒爲單位
動畫延遲delay秒後再開始
動畫的開始時間,默認爲now
動畫的節奏控制,具體看下面的」備註」
動畫的重複次數
若是設置爲YES,表明動畫每次重複執行的效果會跟上一次相反
設置視圖view的過渡效果, transition指定過渡類型, cache設置YES表明使用視圖緩存,性能較好
9、UIImageView的幀動畫
一、定義:
UIImageView可讓一系列的圖片在特定的時間內按順序顯示。
二、屬性解析:
三、方法解析:
10、UIActivityIndicatorView 轉輪動畫
一、定義:
是一個旋轉進度輪,能夠用來告知用戶有一個操做正在進行中,通常用initWithActivityIndicatorStyle初始化(以前的文章有作介紹)。
二、方法解析:
UIActivityIndicatorViewStyleWhiteLarge //大型白色指示器
UIActivityIndicatorViewStyleWhite //標準尺寸白色指示器
UIActivityIndicatorViewStyleGray //灰色指示器,用於白色背景
總結:
一款優秀的app離不開良好的用戶體驗,在如今用戶愈來愈挑剔,設計模式愈來愈成熟和氾濫的狀況下,第一時間抓住用戶的眼球,天然是會得到更高的成功率。另外,界面的多元化,也帶來了不少其餘的使用功能,在賞心悅目的同時,也增長了app的功能擴展。因此,在膜拜大神們華麗設計的同時,本身也不妨嘗試給本身的設計加點花樣。。有了畫筆,剩下的靠本身~