UI部分-iOS動畫

iOS核心動畫-Core Animation

概論

目標(biāo):1. 學(xué)會使用圖層精簡非交互式繪圖;2. 通過核心動畫創(chuàng)建基礎(chǔ)動畫,關(guān)鍵幀動畫,動畫組,轉(zhuǎn)場動畫;3. 學(xué)習(xí)使用UIView對這些動畫簡化操作的裝飾方法.

1. CALayer

1.1 簡介.

CALyer包含在QuartzCore框架中,這是一個跨平臺的框架(iOS 和 MAC OSX);在使用Core Animation開發(fā)動畫的本質(zhì)就是將CALayer中的內(nèi)容轉(zhuǎn)化為位圖從而供硬件操作;

在Core Animation中我們更多是直接操作圖層;UIView中有一個layer屬性作為根圖層,根圖層上可以放其他子圖層,UIView中所有能看到的內(nèi)容都包含在layer中;

1.2 CALayer常用屬性.

iOS中CALayer的設(shè)計主要是為了內(nèi)容展示和動畫操作,它本身并不包含在UIKit中,所以不能響應(yīng)事件.CALyer設(shè)計之初就考慮它的動畫操作功能,因此它的很多屬性在修改時都能形成動畫效果,這種屬性稱為"隱式動畫屬性",很多開發(fā)的時候做平移動畫直接使用隱式動畫即可;

但是,對于UIView的根圖層而言,屬性修改不會形成動畫效果,因為很多情況下根圖層是充當(dāng)容器的作用,如果的它的屬性變動形成的動畫效果會直接影響子圖層.而且根視圖的創(chuàng)建工作完全由系統(tǒng)完成,無法重新創(chuàng)建,只能往根視圖中添加或移除子圖層.層級結(jié)構(gòu)如下:


圖片名稱

列表CALyer的常用屬性如下:

圖片名稱
  • 隱式動畫的本質(zhì)是這些屬性的變動默認(rèn)隱含了CABasicAnimation動畫實現(xiàn).參考Xcode文檔“Animatable Properties”一節(jié)
  • CALayer中很少使用frame屬性,應(yīng)為frame本身不支持動畫效果,使用bounds和position代替.
  • CALayer中使用opacity表示透明度;
  • anchorPoint是圖層錨點: 決定CALayer身上哪個點在position屬性所指的位置 .以自身左上角為原點,范圍0到1;默認(rèn)是[0.5,0.5];
  • (面試題)CALayer為是么使用CGImageRef和CGColorRef?--> QuartzCore是跨平臺的框架,所以不能使用UIKit中的UIColor;
  • 默認(rèn)每個動畫都會包裝一個事務(wù),因此執(zhí)行隱式動畫之前可以設(shè)置這個動畫時長: [CATransaction setAnimation:1]

擴展:若有特殊需求,要關(guān)閉隱式動畫-需要用到動畫事務(wù)CATransaction髓帽,在事務(wù)內(nèi)將隱式動畫關(guān)閉

//開啟事務(wù)
[CATransaction begin];
//禁用隱式動畫
[CATransaction setDisableActions:YES];

在這部分更改圖層屬性.將不會產(chǎn)生隱式動畫

//提交事務(wù)
[CATransaction commit];

1.3 CALayer繪圖

上一章中使用的Quartz 2D繪圖其實已經(jīng)用到了CALayer,當(dāng)利用drawRect:方法繪圖的本質(zhì)就是繪制到圖層中,只是drawRect: 是由UIKit組件進行調(diào)用,所以里面可以使用一些UIKit封裝的方法進行繪圖;

而直接繪制到圖層的方法由于并非UIKit直接調(diào)用,因此只能用原生的Core Graphics方法繪制.
圖層繪圖有兩種方法,不管哪種繪制完成都必須調(diào)用圖層的setNeedDisplay方法 (注意:圖層的方法,不是上一章UIView的方法.)

  1. 通過圖層代理 drawLayer: inContext: 方法.
  2. 通過自定義圖層的 drawInContext: 方法;
1.3.1 代理方法繪圖

步驟:

  1. 指定圖層的代理,所有NSObject都遵守協(xié)議,所以不用手動實現(xiàn)CALayerDelegate;
  2. 在代理對象中重寫-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;
  3. 調(diào)用圖層的setNeedsDisplay方法;

代碼:

#define PHOTO_HEIGHT 50

//自定義圖層
CALayer *Layer = [[CALayer alloc] init];
Layer.bounds = CGRectMake (0,0,PHOTO_HEIGHT,PHOTO_HEIGHT);
layer.position = CGPointMake (160,200);
layer.backgroundColor = [UIColor redColor].CGColor;
layer,cornerRadius = 50/2;
//僅僅設(shè)置圓角,對于圖形而言可以正常顯示,但是對于圖層中繪制的圖片無法正常顯示,需要:
layer.masksToBounds = YES;  來裁剪超出圖層部分 才能顯示出圓角;
//但是同理:陰影效果無法和masksToBounds 同時使用.陰影也會被剪掉;

//設(shè)置邊框
layer.borderColor = [UIColor whiteColor].CGColor;
layer.borderWidth = 2;
//添加到根圖層
[self.view.layer addSublayer: layer ]

//1. 設(shè)置圖層代理
layer.delegate = self;

//2. 調(diào)用
[layer setNeedsDisplay];



//3. 實現(xiàn)代理方法
- (void) -(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
// 傳入的layer是上面定義的圖層   圖形上下文也是此圖層的上下文.
//保存繪圖狀態(tài)
CGContestSaveGState(cox);

//圖形上下文形變,解決圖片倒立 問題 //UIKit 坐標(biāo)系與 Core Graphics 坐標(biāo)系不同;
CGContextScaleCTM (ctx, 1, -1);
CGContextTranslateCTM(cox, 0, -PHOTO_HEIGHT);

UIImage *image = [UIImage imageName:@"photo.png"];
//繪圖      注意:這個位置時相對于圖層  不是屏幕;
CGContextDrawImage(ctx, CGRectMake(0, 0, PHOTO_HEIGHT, PHOTO_HEIGHT), image.CGImage);
 
CGContextRestoreGState(ctx);
}

擴展1.帶陰影效果的圖片裁剪:

由于上面的矛盾,兩個設(shè)置不能同時顯示;換個思路:使用兩個圖層,下面的用來繪制陰影作為容器圖層,上面的用來顯示圖片,裁剪上面的即可;

擴展2.圖層的形變:

  1. 從上面代碼中大家不難發(fā)現(xiàn)使用Core Graphics繪制圖片時會倒立顯示,上面是使用圖形上下文形變來解決這個問題.其實設(shè)置繞x軸旋轉(zhuǎn)180度同樣可以達(dá)到正確顯示目的,只是用圖形上下文做不到旋轉(zhuǎn);
  2. 但是其實圖層有個transform屬性可以直接設(shè)置旋轉(zhuǎn),不需要借助圖形上下文,需要注意的是transform是CATransform3D類型,形變可以在三個維度上進行;(如:CATransform3DMakeTranslation( )抢埋、CATransform3DMakeScale( )、CATransform3DMakeRotation( ))羽嫡。//利用圖層形變解決圖像倒立問題 layer.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);
  3. layer默認(rèn)照錨點旋轉(zhuǎn), 3D向量旋轉(zhuǎn)CATransFrom3DMakeRotation; 后三個是三維坐標(biāo)(x,y,z); xy面作為手機屏幕面.
  4. 既然如此,為什么還要說圖層的形變,直接設(shè)置transform不就行了么;因為形變對于動畫有特殊意義.在動畫開發(fā)中形變往往不是直接設(shè)置transform,而是通過keyPath設(shè)置,這KVC設(shè)置方法和前面沒有區(qū)別,但是這種方式在動畫中很實用,因為它可以很方便的將幾種形變組合到一起使用, 例:[layer setValue:@M_PI forKeyPath:@"transform.rotation.x"];具體屬性可查詢文檔“CATransform3D Key Paths”一節(jié).
1.3.2 使用自定義圖層繪圖

步驟:

  1. 自定義繼承CALyer的類,
  2. 在這個類.m中實現(xiàn)drawInContext: 方法 進行繪圖;
  3. 在UIView中新建這個類對象 調(diào)用圖層 setNeedsDisplay即可顯示出繪圖;

如下:

//1. 創(chuàng)建繼承CALayer的KALayer類;
//2. 在KALayer中重寫drawInContext:(CGContextRef)ctx  進行具體繪圖 
-(void)drawInContext:(CGContextRef)ctx{
//打印一下上下文地址
    NSLog(@"CGContext:%@",ctx);


//// 開始畫圖
    CGContextMoveToPoint(ctx, 94.5, 33.5);
    CGContextAddLineToPoint(ctx,104.02, 47.39);        
    CGContextClosePath(ctx);

    CGContextSetRGBFillColor(ctx, 135.0/255.0, 232.0/255.0, 84.0/255.0, 1);
    CGContextSetRGBStrokeColor(ctx, 135.0/255.0, 232.0/255.0, 84.0/255.0, 1);

    CGContextDrawPath(ctx, kCGPathFillStroke);  
}
    
//3. 在view文件中.
-(instancetype)initWithFrame:(CGRect)frame{
NSLog(@"initWithFrame:");
if (self=[super initWithFrame:frame]) {
    KCLayer *layer=[[KCLayer alloc]init];
    //確定layer位置大小即可
    layer.bounds=CGRectMake(0, 0, 185, 185);
    layer.position=CGPointMake(160,284);
    layer.backgroundColor=[UIColor colorWithRed:0 green:146/255.0 blue:1.0 alpha:1.0].CGColor;
    
    //顯示圖層
    [layer setNeedsDisplay];
    
    [self.layer addSublayer:layer];
    }
return self;
}
 
 //驗證 :drawRect:方法繪圖的本質(zhì)就是繪制到圖層中;
//這里能調(diào)用是應(yīng)為UIView創(chuàng)建圖層會自動設(shè)置圖層代理為其自身
- (void)drawLayer:(CALayer *)layer inContext(CGContextRef)ctx{
    [super drawLayer:layer inContext:ctx];
    //打印上下文
    NSLog(@"CGContext:%@",ctx);
}

- (void)drawRect:(CGRect) rect {
    [super drawRect:rect]
    // 我們在這里獲取到的當(dāng)前圖形上下文正是drawLayer:中傳遞的
    NSLog(@"CGContext:%@",UIGraphicsGetCurrentContext())
}

UIView在顯示時其根圖層會自動創(chuàng)建一個CGContextRef(CALayer本質(zhì)使用的是位圖上下文),同時調(diào)用圖層代理(UIView創(chuàng)建圖層會自動設(shè)置圖層代理為其自身,引申的,不能給給自定義layer的代理設(shè)為view,應(yīng)為view已經(jīng)做自己根圖層的代理了)的draw: inContext:方法并將圖形上下文作為參數(shù)傳遞給這個方法。而在UIView的draw:inContext:方法中會調(diào)用其drawRect:方法衫哥,在drawRect:方法中使用UIGraphicsGetCurrentContext()方法得到的上下文正是前面創(chuàng)建的上下文。


2. Core Animation 核心動畫

簡介.

在iOS中實現(xiàn)一個動畫相當(dāng)簡單襟锐,只要調(diào)用UIView的塊代碼即可實現(xiàn)一個動畫效果撤逢,使用上面UIView封裝的方法進行動畫設(shè)置固然十分方便,但是具體動畫如何實現(xiàn)我們是不清楚的粮坞,而且上面的代碼還有一些問題是無法解決的蚊荣,例如:如何控制動畫的暫停?如何進行動畫的組合莫杈?互例。。筝闹。這就需要了解核心動畫.

0082-640x357.png

核動畫分類:

  1. CAAnimation: 核心動畫基礎(chǔ)類,不直接使用;負(fù)責(zé)動畫 運行時間,速度的控制 ,本身實現(xiàn)了CAMediaTiming協(xié)議;
    1. CAPropertyAnimation: 隱式動畫的基類,不能直接使用;
      • CABasicAnimation:基礎(chǔ)動畫媳叨,通過屬性修改進行動畫參數(shù)控制,只有初始狀態(tài)和結(jié)束狀態(tài)关顷。
      • CAKeyframeAnimation:關(guān)鍵幀動畫糊秆,同樣是通過屬性進行動畫參數(shù)控制,但是同基礎(chǔ)動畫不同的是它可以有多個狀態(tài)控制议双。
    2. CAAnimationGroup:動畫組痘番,動畫組是一種組合模式設(shè)計,可以通過動畫組來進行所有動畫行為的統(tǒng)一控制平痰,組中所有動畫效果可以并發(fā)執(zhí)行汞舱。
    3. CATransition:轉(zhuǎn)場動畫,主要通過濾鏡進行動畫效果設(shè)置宗雇。

基礎(chǔ)動畫/關(guān)鍵幀動畫都是屬于屬性動畫,開發(fā)人員只需要設(shè)置初始值和結(jié)束值,中間的過程動畫(又叫“補間動畫”)由系統(tǒng)自動計算產(chǎn)生昂芜。和基礎(chǔ)動畫不同的是關(guān)鍵幀動畫可以設(shè)置多個屬性值,每兩個屬性中間的補間動畫由系統(tǒng)自動完成赔蒲,因此從這個角度而言基礎(chǔ)動畫又可以看成是只有兩個關(guān)鍵幀的關(guān)鍵幀動畫泌神。

2.1 基礎(chǔ)動畫CABasicAnimation.

很多情況通過基礎(chǔ)動畫就能滿足要求.如果不使用UIView的封裝后方法,一般步驟:

  1. 初始化動畫并指定動畫屬性;決定了執(zhí)行怎樣的動畫,是調(diào)整哪個屬性來執(zhí)行動畫;
  2. 設(shè)置動畫初始值結(jié)束值和其他屬性.
    • 初始值一般省略,默認(rèn)圖層初始狀態(tài).
    • 一般使用KVC,[self.redView.layer setValue:@0.5 forKeyPath:@"transform.scale"];
    • 其他屬性:duration時間,repeatCount次數(shù)(設(shè)為HUGE_VALF表示循環(huán)動畫效果);
  3. 添加動畫到圖層.

示例代碼如下:

//1.創(chuàng)建動畫并指定動畫屬性
CABasicAnimation *basicAnimation=[CABasicAnimation animationWithKeyPath:@"position"];

//2.設(shè)置動畫屬性初始值和結(jié)束值 
//    basicAnimation.fromValue=[NSNumber numberWithInteger:50];//可以不設(shè)置,默認(rèn)為圖層初始狀態(tài)
//toValue表示最終到哪個值    byValue 相對于上一次增加多少值
basicAnimation.toValue=[NSValue valueWithCGPoint:location];

//設(shè)置其他動畫屬性
basicAnimation.duration=5.0;//動畫時間5秒
//  basicAnimation.repeatCount=HUGE_VALF;//設(shè)置重復(fù)次數(shù),HUGE_VALF可看做無窮大嘹履,起到循環(huán)動畫的效果
//  設(shè)置不反彈-兩者不可缺一 
//  basicAnimation.removedOnCompletion=NO;//運行完畢一次后不要移除動畫 
//  basicAnimation.fillMode= KCAFillModeForwards  //保存最新模式 

//3.添加動畫到圖層腻扇,注意key相當(dāng)于給動畫進行命名,以后獲得該動畫時可以使用此名稱獲取
[_layer addAnimation:basicAnimation forKey:@"KCBasicAnimation_Translation"];

存在問題:動畫結(jié)束后動畫圖層回到了原來的位置,當(dāng)然使用UIView封裝的方法是沒這個問題的;問題的原因:圖層動畫的本質(zhì)就是將圖層內(nèi)部的內(nèi)容轉(zhuǎn)化為位圖經(jīng)硬件操作形成一種動畫效果砾嫉,其實圖層本身并沒有任何的變化,動畫效果是假象;

擴展:動畫的暫停與恢復(fù)

核心動畫的運行有一個媒體時間的概念:假設(shè)將一個旋轉(zhuǎn)動畫設(shè)置旋轉(zhuǎn)一周要用時60秒,那么當(dāng)都動畫旋轉(zhuǎn)90度后媒體時間就是15秒. 此時如果要將動畫暫停,只需要讓媒體時間偏離量設(shè)置為15秒,然后動畫運行速度設(shè)置為0時期停止運動;
類似的,如果暫停了50秒后需要恢復(fù)動畫(此時媒體時間為65秒); 這時只要將動畫開始時間設(shè)置為當(dāng)前媒體時間65秒減去暫停時的時刻(之前的設(shè)置的偏移量)即(75-15 =50),即暫停的時時長,與此同時將偏移量重置為0,運行速度設(shè)為1;
這個過程中真正起到暫停作用的是動畫速度;媒體事件偏移量以及恢復(fù)時的開始事件設(shè)置主要是為了讓動畫更加連貫,不會閃跳;

#pragma mark 動畫暫停
-(void)animationPause{
//取得指定圖層動畫的媒體時間幼苛,后面參數(shù)用于指定子圖層,這里不需要
    CFTimeInterval interval=[_layer convertTime:CACurrentMediaTime() fromLayer:nil];
//設(shè)置時間偏移量焕刮,保證暫停時停留在旋轉(zhuǎn)的位置
    [_layer setTimeOffset:interval];
//速度設(shè)置為0舶沿,暫停動畫
    _layer.speed=0;
}

#pragma mark 動畫恢復(fù)
-(void)animationResume{
//獲得暫停的時間
    CFTimeInterval beginTime= CACurrentMediaTime()- _layer.timeOffset;
//設(shè)置偏移量
    _layer.timeOffset=0;
//設(shè)置開始時間
    _layer.beginTime=beginTime;
//設(shè)置動畫速度墙杯,開始運動
    _layer.speed=1.0;
}

注意:動畫暫停針對的是圖層而不是圖層中的某個動畫。;


2.2 關(guān)鍵幀動畫CAKeyframeAnimation.

使用類似于基礎(chǔ)動畫,但可以在無數(shù)個值(稱為關(guān)鍵幀)間改變.有個屬性values數(shù)組,用來接受這些值;

關(guān)鍵幀動畫開發(fā)分為兩種形式:一種是通過設(shè)置不同的屬性值進行關(guān)鍵幀控制括荡,另一種是通過繪制路徑進行關(guān)鍵幀控制高镐。后者優(yōu)先級高于前者,如果設(shè)置了路徑則屬性值就不再起作用畸冲。

屬性關(guān)鍵幀

 //1.創(chuàng)建關(guān)鍵幀動畫并設(shè)置動畫屬性
CAKeyframeAnimation *keyframeAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"];

//2.設(shè)置關(guān)鍵幀,這里有四個關(guān)鍵幀
NSValue *key1=[NSValue valueWithCGPoint:_layer.position];//對于關(guān)鍵幀動畫初始值不能省略
NSValue *key2=[NSValue valueWithCGPoint:CGPointMake(80, 220)];
NSValue *key3=[NSValue valueWithCGPoint:CGPointMake(45, 300)];
NSValue *key4=[NSValue valueWithCGPoint:CGPointMake(55, 400)];
NSArray *values=@[key1,key2,key3,key4];
keyframeAnimation.values=values;
//設(shè)置其他屬性
keyframeAnimation.duration=8.0;
keyframeAnimation.beginTime=CACurrentMediaTime()+2;//設(shè)置延遲2秒執(zhí)行


//3.添加動畫到圖層嫉髓,添加動畫后就會執(zhí)行動畫
[_layer addAnimation:keyframeAnimation forKey:@"KCKeyframeAnimation_Position"];

路徑關(guān)鍵幀

//1.創(chuàng)建關(guān)鍵幀動畫并設(shè)置動畫屬性
CAKeyframeAnimation *keyframeAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"];

//2.設(shè)置路徑
//繪制貝塞爾曲線
CGPathRef path=CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, _layer.position.x, _layer.position.y);//移動到起始點
CGPathAddCurveToPoint(path, NULL, 160, 280, -30, 300, 55, 400);//繪制二次貝塞爾曲線

keyframeAnimation.path=path;//設(shè)置path屬性
CGPathRelease(path);//釋放路徑對象
//設(shè)置其他屬性
keyframeAnimation.duration=8.0;
keyframeAnimation.beginTime=CACurrentMediaTime()+2;//設(shè)置延遲2秒執(zhí)行


//3.添加動畫到圖層,添加動畫后就會執(zhí)行動畫
[_layer addAnimation:keyframeAnimation forKey:@"KCKeyframeAnimation_Position"];

不同動畫效果如下:

<img src="http://images.cnitblog.com/blog/62046/201409/150628429879513.png
" width = "120" height = "200" alt="圖片名稱" align=center />
<img src="http://images.cnitblog.com/blog/62046/201409/150628441904812.png
" width = "120" height = "200" alt="路徑幀" align=center />

補充-其他屬性

keyTimes:各個關(guān)鍵幀的時間控制,值是各關(guān)鍵幀所占設(shè)置的動畫時間的比例,(可以大于1);

caculationMode:動畫計算模式.拿上面keyValues動畫舉例邑闲,之所以1到2幀能形成連貫性動畫而不是直接從第1幀經(jīng)過8/3秒到第2幀是因為動畫模式是連續(xù)的(值為kCAAnimationLinear算行,這是計算模式的默認(rèn)值);而如果指定了動畫模式為kCAAnimationDiscrete離散的那么你會看到動畫從第1幀經(jīng)過8/3秒直接到第2幀苫耸,中間沒有任何過渡州邢。其他動畫模式還有:kCAAnimationPaced(均勻執(zhí)行,會忽略keyTimes)褪子、kCAAnimationCubic(平滑執(zhí)行量淌,對于位置變動關(guān)鍵幀動畫運行軌跡更平滑)、kCAAnimationCubicPaced(平滑均勻執(zhí)行)嫌褪。
下圖描繪出了幾種動畫模式的關(guān)系(橫坐標(biāo)是運行時間呀枢,縱坐標(biāo)是動畫屬性[例如位置、透明度等]):
<img src="http://images.cnitblog.com/blog/62046/201409/150628454405097.png
" width = "300" height = "200" alt="圖片名稱" align=center />

2.3 動畫組CAAnimationGroup.

實際開發(fā)中一個物體的運動往往是復(fù)合運動渔扎,單一屬性的運動情況比較少硫狞,但恰恰屬性動畫每次進行動畫設(shè)置時一次只能設(shè)置一個屬性進行動畫控制,這樣一來要做一個復(fù)合運動的動畫就必須創(chuàng)建多個屬性動畫進行組合信轿。動畫組的產(chǎn)生就是基于這樣一種情況而產(chǎn)生的.

動畫組是一系列動畫的組合晃痴,凡是添加到動畫組中的動畫都受控于動畫組,這樣一來各類動畫公共的行為就可以統(tǒng)一進行控制而不必單獨設(shè)置财忽,而且放到動畫組中的各個動畫可以并發(fā)執(zhí)行倘核,共同構(gòu)建出復(fù)雜的動畫效果。

一般步驟:首先單獨創(chuàng)建單個動畫(可以是基礎(chǔ)動畫也可以是關(guān)鍵幀動畫),之后添加到動畫組上,再把動畫組添加到圖層,就可以統(tǒng)一,同時執(zhí)行這些動畫.

//1.創(chuàng)建動畫組
CAAnimationGroup *animationGroup=[CAAnimationGroup animation];

//2.設(shè)置組中的動畫和其他屬性
CABasicAnimation *basicAnimation=[self rotationAnimation]; //是封裝上面的基礎(chǔ)動畫代碼
CAKeyframeAnimation *keyframeAnimation=[self translationAnimation];//封裝上面幀動畫代碼
animationGroup.animations=@[basicAnimation,keyframeAnimation];

animationGroup.duration=10.0;//設(shè)置動畫時間即彪,如果動畫組中動畫已經(jīng)設(shè)置過動畫屬性則不再生效
animationGroup.beginTime=CACurrentMediaTime()+5;//延遲五秒執(zhí)行

//3.給圖層添加動畫
[_layer addAnimation:animationGroup forKey:nil];
2.4 轉(zhuǎn)場動畫CATransition

蘋果封裝的一個場景以動畫形式轉(zhuǎn)到另一個場景.
步驟:

  1. 創(chuàng)建轉(zhuǎn)場動畫
  2. 設(shè)置轉(zhuǎn)場類型,子類型(可選)以及其他屬性;
  3. 設(shè)置轉(zhuǎn)場后的新視圖并添加動畫到圖層.

下表列出了常用的轉(zhuǎn)場類型(注意私有API是蘋果官方?jīng)]有公開的動畫類型紧唱,但是目前通過字符串仍然可以使用):

動畫類型 說明 對應(yīng)常量 是否支持方向設(shè)置
公開API
fade 淡出效果 kCATransitionFade
movein 新視圖移動到舊視圖上 kCATransitionMoveIn
push 新視圖推出舊視圖 kCATransitionPush
reveal 移開舊視圖顯示新視圖 kCATransitionReveal
私有API 私有API只能通過字符串訪問
cube 立方體翻轉(zhuǎn)效果
oglFlip 翻轉(zhuǎn)效果
suckEffect 收縮效果 無
rippleEffect 水滴波紋效果
pageCurl 向上翻頁效果
pageUnCurl 向下翻頁效果
cameralIrisHollowOpen 攝像頭打開效果
cameraIrisHollowClose 攝像頭關(guān)閉效果

另外對于支持方向設(shè)置的動畫類型還包含子類型:

動畫子類型 說明
kCATransitionFromRight 從右側(cè)轉(zhuǎn)場
kCATransitionFromLeft 從左側(cè)轉(zhuǎn)場
kCATransitionFromTop 從頂部轉(zhuǎn)場
kCATransitionFromBottom 從底部轉(zhuǎn)場
//1.創(chuàng)建轉(zhuǎn)場動畫對象
CATransition *transition=[[CATransition alloc]init];

//2.設(shè)置動畫類型,注意對于蘋果官方?jīng)]公開的動畫類型只能使用字符串,并沒有對應(yīng)的常量定義
transition.type=@"cube";

    //設(shè)置子類型
if (isNext) {
    transition.subtype=kCATransitionFromRight;
}else{
    transition.subtype=kCATransitionFromLeft;
}
//設(shè)置動畫時常
transition.duration=1.0f;

//3.設(shè)置轉(zhuǎn)場后的新視圖 添加轉(zhuǎn)場動畫
_imageView.image=[self getImage:isNext];
[_imageView.layer addAnimation:transition forKey:@"KCTransitionAnimation"];
2.5 UIImageView的序列幀動畫.

通過設(shè)置UIImageView的animationImages屬性隶校,然后調(diào)用它的startAnimating方法去播放這組圖片漏益。(存在著很大的性能問題,并且這種方法一旦設(shè)置完圖片中間的過程就無法控制了深胳。TOM貓例)

但是對于一些事物的運動又不得不選擇使用逐幀動畫绰疤,例如人得運動,這是一個高度復(fù)雜的運動舞终,基本動畫轻庆、關(guān)鍵幀動畫是不可能解決的癣猾。所大家一定要注意在循環(huán)方法中盡可能的降低算法復(fù)雜度,同時保證循環(huán)過程中內(nèi)存峰值盡可能低(延遲釋放)余爆。
可以和其他動畫組合使用.


3. UIView動畫封裝

UIView本身對于基本動畫和關(guān)鍵幀動畫纷宇、轉(zhuǎn)場動畫都有相應(yīng)的封裝,在對動畫細(xì)節(jié)沒有特殊要求的情況下使用起來也要簡單的多蛾方∠翊罚可以說在日常開發(fā)中90%以上的情況使用UIView的動畫封裝方法都可以搞定.

3.1 基礎(chǔ)動畫

原理講過直接上封裝的方法:

 //方法1:block方式
/*開始動畫,UIView的動畫方法執(zhí)行完后動畫會停留在重點位置桩砰,而不需要進行任何特殊處理
 duration:執(zhí)行時間
 delay:延遲時間
 options:動畫設(shè)置作岖,例如自動恢復(fù)、勻速運動等
 completion:動畫完成回調(diào)方法
 */
//    [UIView animateWithDuration:5.0 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
//        _imageView.center=location;
//    } completion:^(BOOL finished) {
//        NSLog(@"Animation end.");
//    }];



//方法2:靜態(tài)方法
//開始動畫
[UIView beginAnimations:@"KCBasicAnimation" context:nil];
[UIView setAnimationDuration:5.0];
//[UIView setAnimationDelay:1.0];//設(shè)置延遲
//[UIView setAnimationRepeatAutoreverses:NO];//是否回復(fù)
//[UIView setAnimationRepeatCount:10];//重復(fù)次數(shù)
//[UIView setAnimationStartDate:(NSDate *)];//設(shè)置動畫開始運行的時間
//[UIView setAnimationDelegate:self];//設(shè)置代理
//[UIView setAnimationWillStartSelector:(SEL)];//設(shè)置動畫開始運動的執(zhí)行方法
//[UIView setAnimationDidStopSelector:(SEL)];//設(shè)置動畫運行結(jié)束后的執(zhí)行方法

_imageView.center=location;


//提交動畫
[UIView commitAnimations];
擴展:彈簧動畫效果.

由于在iOS開發(fā)中彈性動畫使用很普遍五芝,所以在iOS7蘋果官方直接提供了一個方法用于彈性動畫開發(fā).

/*創(chuàng)建彈性動畫  - block
 damping:阻尼痘儡,范圍0-1,阻尼越接近于0枢步,彈性效果越明顯
 velocity:彈性復(fù)位的速度
*/
[UIView animateWithDuration:5.0 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveLinear animations:^{
    _imageView.center = location; //CGPointMake(160, 284);
} completion:nil];
補充:options-動畫參數(shù)

在動畫方法中有一個option參數(shù)沉删,UIViewAnimationOptions類型,它是一個枚舉類型醉途,動畫參數(shù)分為三類矾瑰,可以組合使用:


  • 常規(guī)動畫屬性設(shè)置(可以同時選擇多個進行設(shè)置)

UIViewAnimationOptionLayoutSubviews:動畫過程中保證子視圖跟隨運動。

UIViewAnimationOptionAllowUserInteraction:動畫過程中允許用戶交互隘擎。

UIViewAnimationOptionBeginFromCurrentState:所有視圖從當(dāng)前狀態(tài)開始運行殴穴。

UIViewAnimationOptionRepeat:重復(fù)運行動畫。

UIViewAnimationOptionAutoreverse :動畫運行到結(jié)束點后仍然以動畫方式回到初始點货葬。

UIViewAnimationOptionOverrideInheritedDuration:忽略嵌套動畫時間設(shè)置采幌。

UIViewAnimationOptionOverrideInheritedCurve:忽略嵌套動畫速度設(shè)置。關(guān)鍵幀動畫沒有

UIViewAnimationOptionAllowAnimatedContent:動畫過程中重繪視圖(注意僅僅適用于轉(zhuǎn)場動畫)震桶。

UIViewAnimationOptionShowHideTransitionViews:視圖切換時直接隱藏舊視圖休傍、顯示新視圖,而不是將舊視圖從父視圖移除(僅僅適用于轉(zhuǎn)場動畫)
UIViewAnimationOptionOverrideInheritedOptions :不繼承父動畫設(shè)置或動畫類型蹲姐。


  • 動畫速度控制(可從其中選擇一個設(shè)置)

UIViewAnimationOptionCurveEaseInOut:動畫先緩慢磨取,然后逐漸加速。

UIViewAnimationOptionCurveEaseIn :動畫逐漸變慢柴墩。

UIViewAnimationOptionCurveEaseOut:動畫逐漸加速忙厌。

UIViewAnimationOptionCurveLinear :動畫勻速執(zhí)行,默認(rèn)值江咳。

  • 轉(zhuǎn)場類型(僅適用于轉(zhuǎn)場動畫設(shè)置逢净,可以從中選擇一個進行設(shè)置,基本動畫、關(guān)鍵幀動畫不需要設(shè)置)

UIViewAnimationOptionTransitionNone:沒有轉(zhuǎn)場動畫效果汹胃。

UIViewAnimationOptionTransitionFlipFromLeft :從左側(cè)翻轉(zhuǎn)效果婶芭。

UIViewAnimationOptionTransitionFlipFromRight:從右側(cè)翻轉(zhuǎn)效果。

UIViewAnimationOptionTransitionCurlUp:向后翻頁的動畫過渡效果着饥。

UIViewAnimationOptionTransitionCurlDown :向前翻頁的動畫過渡效果犀农。

UIViewAnimationOptionTransitionCrossDissolve:舊視圖溶解消失顯示下一個新視圖的效果。

UIViewAnimationOptionTransitionFlipFromTop :從上方翻轉(zhuǎn)效果宰掉。

UIViewAnimationOptionTransitionFlipFromBottom:從底部翻轉(zhuǎn)效果呵哨。

3.2 關(guān)鍵幀動畫

從iOS7開始UIView動畫中封裝了關(guān)鍵幀動畫

/*關(guān)鍵幀動畫
 options:
 */
[UIView animateKeyframesWithDuration:5.0 delay:0 options: UIViewAnimationOptionCurveLinear| UIViewAnimationOptionCurveLinear animations:^{
    //第二個關(guān)鍵幀(準(zhǔn)確的說第一個關(guān)鍵幀是開始位置):從0秒開始持續(xù)50%的時間,也就是5.0*0.5=2.5秒
    [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{
        _imageView.center=CGPointMake(80.0, 220.0);
    }];
    //第三個關(guān)鍵幀轨奄,從0.5*5.0秒開始孟害,持續(xù)5.0*0.25=1.25秒
    [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.25 animations:^{
        _imageView.center=CGPointMake(45.0, 300.0);
    }];
    //第四個關(guān)鍵幀:從0.75*5.0秒開始,持所需5.0*0.25=1.25秒
    [UIView addKeyframeWithRelativeStartTime:0.75 relativeDuration:0.25 animations:^{
        _imageView.center=CGPointMake(55.0, 400.0);
    }];
    
} completion:^(BOOL finished) {
    NSLog(@"Animation end.");
}];
  • 關(guān)鍵幀的options,絕大多數(shù)同上,另有動畫模式設(shè)置.

  • 動畫模式設(shè)置(同前面關(guān)鍵幀動畫動畫模式一一對應(yīng)挪拟,可以從其中選擇一個進行設(shè)置)

UIViewKeyframeAnimationOptionCalculationModeLinear:連續(xù)運算模式挨务。

UIViewKeyframeAnimationOptionCalculationModeDiscrete :離散運算模式。

UIViewKeyframeAnimationOptionCalculationModePaced:均勻執(zhí)行運算模式玉组。

UIViewKeyframeAnimationOptionCalculationModeCubic:平滑運算模式谎柄。

UIViewKeyframeAnimationOptionCalculationModeCubicPaced:平滑均勻運算模式。

注意:前面說過關(guān)鍵幀動畫有兩種形式惯雳,上面演示的是屬性值關(guān)鍵幀動畫朝巫,路徑關(guān)鍵幀動畫目前UIView還不支持。

3.3 轉(zhuǎn)場動畫

從iOS4.0開始石景,UIView直接封裝了轉(zhuǎn)場動畫.

 [UIView transitionWithView:_imageView duration:1.0 options:option animations:^{
    _imageView.image=[self getImage:isNext];
} completion:nil];

#pragma mark 取得當(dāng)前圖片
-(UIImage *)getImage:(BOOL)isNext{
    if (isNext) {
        _currentIndex=(_currentIndex+1)%IMAGE_COUNT;
    }else{
        _currentIndex=(_currentIndex-1+IMAGE_COUNT)%IMAGE_COUNT;
    }
    NSString *imageName=[NSString stringWithFormat:@"%i.jpg",_currentIndex];
    return [UIImage imageNamed:imageName];
}

上面的轉(zhuǎn)場動畫演示中劈猿,其實僅僅有一個視圖UIImageView做轉(zhuǎn)場動畫,每次轉(zhuǎn)場通過切換UIImageView的內(nèi)容而已潮孽。如果有兩個完全不同的視圖揪荣,并且每個視圖布局都很復(fù)雜,此時要在這兩個視圖之間進行轉(zhuǎn)場可以使用+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(4_0)方法進行兩個視圖間的轉(zhuǎn)場恩商,需要注意的是默認(rèn)情況下轉(zhuǎn)出的視圖會從父視圖移除变逃,轉(zhuǎn)入后重新添加必逆,可以通過 UIViewAnimationOptionShowHideTransitionViews參數(shù)設(shè)置怠堪,設(shè)置此參數(shù)后轉(zhuǎn)出的視圖會隱藏(不會移除)轉(zhuǎn)入后再顯示。

注意:轉(zhuǎn)場動畫設(shè)置參數(shù)完全同基本動畫參數(shù)設(shè)置名眉;同直接使用轉(zhuǎn)場動畫不同的是使用UIView的裝飾方法進行轉(zhuǎn)場動畫其動畫效果較少粟矿,因為這里無法直接使用私有API。

參考博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末损拢,一起剝皮案震驚了整個濱河市陌粹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌福压,老刑警劉巖掏秩,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件或舞,死亡現(xiàn)場離奇詭異,居然都是意外死亡蒙幻,警方通過查閱死者的電腦和手機映凳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來邮破,“玉大人诈豌,你說我怎么就攤上這事∈愫停” “怎么了矫渔?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長摧莽。 經(jīng)常有香客問我庙洼,道長,這世上最難降的妖魔是什么镊辕? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任送膳,我火速辦了婚禮,結(jié)果婚禮上丑蛤,老公的妹妹穿的比我還像新娘叠聋。我一直安慰自己,他們只是感情好受裹,可當(dāng)我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布碌补。 她就那樣靜靜地躺著,像睡著了一般棉饶。 火紅的嫁衣襯著肌膚如雪厦章。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天照藻,我揣著相機與錄音袜啃,去河邊找鬼。 笑死幸缕,一個胖子當(dāng)著我的面吹牛群发,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播发乔,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼熟妓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了栏尚?” 一聲冷哼從身側(cè)響起起愈,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后抬虽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體官觅,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年阐污,在試婚紗的時候發(fā)現(xiàn)自己被綠了缰猴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡疤剑,死狀恐怖滑绒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情隘膘,我是刑警寧澤疑故,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站弯菊,受9級特大地震影響纵势,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜管钳,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一钦铁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧才漆,春花似錦牛曹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鸳玩,卻和暖如春阅虫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背不跟。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工颓帝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人窝革。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓购城,卻偏偏與公主長得像,于是被迫代替她去往敵國和親聊闯。 傳聞我的和親對象是個殘疾皇子工猜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內(nèi)容

  • 在iOS中隨處都可以看到絢麗的動畫效果,實現(xiàn)這些動畫的過程并不復(fù)雜菱蔬,今天將帶大家一窺ios動畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,502評論 6 30
  • 在iOS中隨處都可以看到絢麗的動畫效果,實現(xiàn)這些動畫的過程并不復(fù)雜拴泌,今天將帶大家一窺iOS動畫全貌魏身。在這里你可以看...
    F麥子閱讀 5,113評論 5 13
  • 概覽 在iOS中隨處都可以看到絢麗的動畫效果,實現(xiàn)這些動畫的過程并不復(fù)雜蚪腐,今天將帶大家一窺iOS動畫全貌箭昵。在這里你...
    Yiart閱讀 3,819評論 3 34
  • 在iOS實際開發(fā)中常用的動畫無非是以下四種:UIView動畫,核心動畫回季,幀動畫家制,自定義轉(zhuǎn)場動畫。 1.UIView...
    請叫我周小帥閱讀 3,102評論 1 23
  • 概覽 在iOS中隨處都可以看到絢麗的動畫效果,實現(xiàn)這些動畫的過程并不復(fù)雜鼻忠,今天將帶大家一窺iOS動畫全貌涵但。在這里你...
    被吹落的風(fēng)閱讀 1,565評論 1 2