記錄一下學(xué)習(xí)的筆記
核心動畫
- 核心動畫基本概念
- 基本動畫
- 關(guān)鍵幀動畫
- 動畫組
- 轉(zhuǎn)場動畫
Core Animation簡介
-
Core Animation
,中文翻譯譯為核心動畫,它是一組非常強(qiáng)大動畫處理API
,使用它能做出非常炫麗的動畫效果,而且往往是事半功倍。也就是說,使用少量的代碼就可以實(shí)現(xiàn)非常強(qiáng)大的功能。 -
Core Animation
也可以用在Mac OS X
和iOS
平臺。 -
Core Animation
的動畫執(zhí)行過程都是在后臺操作的,不會阻塞主線程。 - 要注意的是,
Core Animation
是直接作用在CALayer
上的,并非UIView
。
核心動畫繼承結(jié)構(gòu)
基本動畫
一、位移動畫
效果圖
: 注意,這里動畫執(zhí)行完畢后,狀態(tài)是會還原到開始動畫的位置,我們可以繼續(xù)點(diǎn)擊屏幕,再次執(zhí)行動畫。可以使用removedOnCompletion
和fillMode
控制動畫執(zhí)行完畢后的狀態(tài),詳情繼續(xù)往下看。
-
1、創(chuàng)建一個藍(lán)色的
View
Snip20160324_5.png 2、點(diǎn)擊觸發(fā)位移動畫
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 1、初始化動畫對象
CABasicAnimation *anim = [CABasicAnimation animation];
// 2、設(shè)置屬性值
anim.keyPath = @"transform.translation.x";
anim.toValue = @100;
// 一個layer里面可能有多個動畫,forKey可以方便管理
[self.blueView.layer addAnimation: anim forKey: nil];
}
- 3、基本屬性詳解
-
a、
keyPath
: 告訴系統(tǒng)要執(zhí)行什么樣的動畫,可以在Xcode Documentation
中查詢可以使用的keyPath
的值。
Snip20160324_6.png b、
toValue
: 通過動畫,要把layer移動到哪兒。c、
removedOnCompletion
和fillMode
配合使用, 可以讓動畫執(zhí)行完畢后,圖層會保持顯示動畫執(zhí)行后的狀態(tài)。但在實(shí)質(zhì)上,圖層的屬性值還是動畫執(zhí)行前的初始值,并沒有真正被改變.
-
看以下的代碼,分別在動畫開始前打印了
layer
的position
的值,動畫執(zhí)行完畢后也打印了layer
的position
的值,不過要設(shè)置一下動畫的代理。
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent: (UIEvent *)event
{
NSLog(@"開始時(shí)position的值:%@", NSStringFromCGPoint(self.blueView.layer.position));
// 1、初始化動畫對象
CABasicAnimation *anim = [CABasicAnimation animation];
// 2、設(shè)置屬性值
anim.keyPath = @"transform.translation.x";
anim.toValue = @100;
// 3、動畫完成后是否刪除動畫
anim.removedOnCompletion = NO;
anim.fillMode = kCAFillModeForwards;
anim.delegate = self;
// anim.fillMode = @"forwards"; // 也是支持字符串的
// anim.fillMode = @"backwards"; // 默認(rèn)的
// 一個layer里面可能有多個動畫,forKey可以方便管理
[self.blueView.layer addAnimation: anim forKey: nil];
}
- (void)animationDidStart:(CAAnimation *)anim
{
NSLog(@"開始動畫");
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
NSLog(@"執(zhí)行后position的值:%@", NSStringFromCGPoint(self.blueView.layer.position));
}
效果圖
:
點(diǎn)擊屏幕,layer停留在動畫結(jié)束的那一位置。
實(shí)際的position
的值并沒有改變
二、心跳動畫
效果圖:
-
1、創(chuàng)建一個
UIImageView
并設(shè)置心跳圖片
Snip20160324_8.png 2、點(diǎn)擊屏幕觸發(fā)動畫, 主要學(xué)習(xí)一下
duration
、repeatCount
與autoreverses
屬性。
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 創(chuàng)建動畫對象
CABasicAnimation *anim = [CABasicAnimation animation];
anim.keyPath = @"transform.scale"; // transform.scale 表示長和寬都縮放
anim.toValue = @0; // @0 縮放到最小
anim.duration = 0.5; // 設(shè)置動畫執(zhí)行時(shí)間
anim.repeatCount = MAXFLOAT; // MAXFLOAT 表示動畫執(zhí)行次數(shù)為無限次
anim.autoreverses = YES; // 控制動畫反轉(zhuǎn) 默認(rèn)情況下動畫從尺寸1到0的過程中是有動畫的,但是從0到1的過程中是沒有動畫的,設(shè)置autoreverses屬性可以讓尺寸0到1也是有過程的
[self.imageView.layer addAnimation: anim forKey: nil];
}
楨動畫
是
CApropertyAnimation
的子類,跟CABasicAnimation
的區(qū)別是:CABasicAnimation
只能從一個數(shù)值(fromValue
)變到另一個數(shù)值(toValue
),而CAKeyframeAnimation
會使用一個NSArray
保存這些數(shù)值, 也可以使用UIBezierPath
來繪制動畫路徑。
屬性解析:
-
values
:就是上述的NSArray
對象。里面的元素稱為”關(guān)鍵幀”(keyframe
)。動畫對象會在指定的時(shí)間(duration
)內(nèi),依次顯示values
數(shù)組中的每一個關(guān)鍵幀。 -
path
:可以設(shè)置一個CGPathRef\CGMutablePathRef
,讓層跟著路徑移動。path
只對CALayer
的anchorPoint
和position
起作用。如果你設(shè)置了path
,那么values
將被忽略。 -
keyTimes
:可以為對應(yīng)的關(guān)鍵幀指定對應(yīng)的時(shí)間點(diǎn),其取值范圍為0到1.0,keyTimes中的每一個時(shí)間值都對應(yīng)values中的每一幀.當(dāng)keyTimes
沒有設(shè)置的時(shí)候,各個關(guān)鍵幀的時(shí)間是平分的。
說明:
CABasicAnimation
可看做是最多只有2個關(guān)鍵幀的CAKeyframeAnimation
。
一、抖動效果
效果圖:
-
1、創(chuàng)建一個
UIImageView
Snip20160324_9.png 2、點(diǎn)擊屏幕觸發(fā)抖動效果
#define angle2Radio(angle) ((angle) * M_PI / 180.0) // 旋轉(zhuǎn)角度的宏
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
anim.keyPath = @"transform.rotation"; // rotation.x、rotation.y與rotation.z 默認(rèn)是z
anim.values = @[@(angle2Radio(-5)), @(angle2Radio(5)), @(angle2Radio(-5))]; // 把度數(shù)轉(zhuǎn)換為弧度 度數(shù)/180*M_PI
anim.repeatCount = MAXFLOAT; // 動畫執(zhí)行次數(shù)無限次
[self.imageView.layer addAnimation: anim forKey: nil];
}
轉(zhuǎn)場動畫
CAAnimation的子類,用于做轉(zhuǎn)場動畫,能夠?yàn)閷犹峁┮瞥銎聊缓鸵迫肫聊坏膭赢嬓ЧOS比Mac OS X的轉(zhuǎn)場動畫效果少一點(diǎn)
UINavigationController就是通過CATransition實(shí)現(xiàn)了將控制器的視圖推入屏幕的動畫效果
屬性解析:
-
type
:動畫過渡類型 -
subtype
:動畫過渡方向 -
startProgress
:動畫起點(diǎn)(在整體動畫的百分比) -
endProgress
:動畫終點(diǎn)(在整體動畫的百分比)
效果圖:
-
1、創(chuàng)建一個
UIImageView
Snip20160324_11.png 2、點(diǎn)擊屏幕觸發(fā)轉(zhuǎn)場效果
static int _i = 1;
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 0、切換圖片
_i++;
if (_i > 3) {
_i = 1;
}
self.imageView.image = [UIImage imageNamed: [NSString stringWithFormat: @"%d", _i]];
// 1、創(chuàng)建轉(zhuǎn)場動畫
CATransition *trans = [CATransition animation];
trans.duration = 1;
// 2、設(shè)置轉(zhuǎn)場類型
trans.type = @"cude";
[self.imageView.layer addAnimation: trans forKey: nil];
}
- 3、
type
類型的值
類型字符串 | 效果說明 | 關(guān)鍵字 | 方向 |
---|---|---|---|
fade | 交叉淡化過渡 | YES | |
push | 新視圖把舊視圖推出去 | YES | |
moveIn | 新視圖移到舊視圖上面 | YES | |
reveal | 將舊視圖移開,顯示下面的新視圖 | YES | |
cube | 立體翻轉(zhuǎn)效果 | ||
oglflip | 上下左右翻轉(zhuǎn)效果 | ||
suckEffect | 收縮效果,如同一塊布被抽走 | NO | |
rippleEffect | 水滴效果 | NO | |
pageCurl | 向上翻頁效果 | ||
pageUnCurl | 向下翻頁效果 | ||
cameraIrisHollowOpen | 相機(jī)鏡頭打開效果 | NO | |
cameraIrisHollowClose | 相機(jī)鏡頭關(guān)閉效果 | NO |
動畫組
動畫組,是
CAAnimation
的子類,可以保存一組動畫對象,將CAAnimationGroup
對象加入層后,組中所有動畫對象可以同時(shí)并發(fā)運(yùn)行。
屬性說明:
- animations:用來保存一組動畫對象的NSArray
- 默認(rèn)情況下,一組動畫對象是同時(shí)運(yùn)行的,也可以通過設(shè)置動畫對象的beginTime屬性來更改動畫的開始時(shí)間
一、移動、縮小同時(shí)進(jìn)行的動畫
效果圖:
- 1、創(chuàng)建一個藍(lán)色的
UIView
- 2、第一種方法,創(chuàng)建兩個基本動畫,缺點(diǎn)有些屬性需要重復(fù)設(shè)置
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
CABasicAnimation *anim1 = [CABasicAnimation animation];
anim1.keyPath = @"transform.translation.y";
anim1.toValue = @100;
anim1.duration = 2;
anim1.removedOnCompletion = NO;
anim1.fillMode = kCAFillModeForwards;
CABasicAnimation *anim2 = [CABasicAnimation animation];
anim2.keyPath = @"transform.scale";
anim2.toValue = @0.5;
anim2.duration = 2;
anim2.removedOnCompletion = NO;
anim2.fillMode = kCAFillModeForwards;
[self.blueView.layer addAnimation: anim1 forKey: nil];
[self.blueView.layer addAnimation: anim2 forKey: nil];
}
- 3、第二種方法,組動畫, 可以設(shè)置公共屬性
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
CAAnimationGroup *groupAnim = [CAAnimationGroup animation];
groupAnim.duration = 2;
groupAnim.removedOnCompletion = NO;
groupAnim.fillMode = kCAFillModeForwards;
CABasicAnimation *anim1 = [CABasicAnimation animation];
anim1.keyPath = @"transform.translation.y";
anim1.toValue = @100;
CABasicAnimation *anim2 = [CABasicAnimation animation];
anim2.keyPath = @"transform.scale";
anim2.toValue = @0.5;
groupAnim.animations = @[anim1, anim2];
[self.blueView.layer addAnimation: groupAnim forKey: nil];
}
UIView動畫和核心動畫的區(qū)別和選擇
區(qū)別:
- 1、核心動畫只作用于
Layer
。 - 2、核心動畫看到的一切都是假像,真實(shí)值并沒有被修改(詳情查看基本動畫第一個例子)。
選擇:
- 1、什么時(shí)候使用
UIView
動畫: 當(dāng)與用戶交互的時(shí)候,使用UIView
,不需要與用戶進(jìn)行交互時(shí),使用兩個都可以。 - 2、什么時(shí)候使用核心動畫:當(dāng)做幀動畫,轉(zhuǎn)場動畫的時(shí)候使用