核心動(dòng)畫(huà)
- 動(dòng)畫(huà)可以大致分為兩種,一種是UIView上的,一種是CALayer層的,其實(shí)本質(zhì)都是基于CoreAnimation框架下,CALayer層的被稱為核心動(dòng)畫(huà),功能更強(qiáng)大,UIView的動(dòng)畫(huà)是基于核心動(dòng)畫(huà)的封裝,用起來(lái)更加方便,由于CALayer層的核心動(dòng)畫(huà)是QuartzCore框架中的,可移植性高,OSX和ios上都可以用,但是在開(kāi)發(fā)過(guò)程中用到的UIColor粪摘、UIImage是定義在UIKit框架中的,只能在iOS中使用,也就意味著利用核心動(dòng)畫(huà)的時(shí)候需要轉(zhuǎn)換成CoreGraphics框架下的數(shù)據(jù)類型(即CGImageRef屡萤、CGColorRef)
1.png
UIView上的動(dòng)畫(huà)
UIImageView的動(dòng)畫(huà)(gif動(dòng)畫(huà))
//UIImageView的動(dòng)畫(huà)
- (void)gif
{
NSMutableArray *arrayData = [NSMutableArray array];
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
for (int i = 0; i < 31; i++) {
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",(i + 1)]];
[arrayData addObject:image];
}
//播放的圖片
self.imageView.animationImages = arrayData;
//播放時(shí)間
self.imageView.animationDuration = 1;
//播放次數(shù)
self.imageView.animationRepeatCount = INT_MAX;
//開(kāi)始播放
[self.imageView startAnimating];
//添加
[self.view addSubview:self.imageView];
}
系統(tǒng)提供的風(fēng)火輪動(dòng)畫(huà)(菊花)
//系統(tǒng)提供的菊花
- (void)activityIndicatorView
{
//菊花
self.acView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
self.acView.center = self.view.center;
[self.view addSubview:self.acView];
//修改顏色
self.acView.color = [UIColor grayColor];
//開(kāi)始播放
[self.acView startAnimating];
//停止菊花
self.acView.hidesWhenStopped = NO;
//停止播放
// [self.acView stopAnimating];
}
block動(dòng)畫(huà)(最簡(jiǎn)單最常用的動(dòng)畫(huà),以animateWith開(kāi)頭,帶有一個(gè)block)
//最常用最簡(jiǎn)單的動(dòng)畫(huà)(block方法)
- (void)blockView
{
__block UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 40, 40)];
coustomView.backgroundColor = [UIColor greenColor];
[self.view addSubview:coustomView];
self.view.backgroundColor = [UIColor yellowColor];
//1.動(dòng)畫(huà)的執(zhí)行時(shí)間 2.動(dòng)畫(huà)的執(zhí)行結(jié)果 3. 動(dòng)畫(huà)的執(zhí)行完畢回調(diào)
[UIView animateWithDuration:3 animations:^{
self.view.backgroundColor = [UIColor redColor];
coustomView.frame = CGRectMake(50, 50, 80, 20);
} completion:^(BOOL finished) {
//完成之后會(huì)來(lái)到這里
NSLog(@"動(dòng)畫(huà)執(zhí)行完畢");
}];
}
與block效果一樣的動(dòng)畫(huà),創(chuàng)建方式不同(方法基本是對(duì)應(yīng)的)
//跟block是對(duì)應(yīng)的,效果是相同的,只是方式不一樣
- (void)UIView
{
UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
coustomView.backgroundColor = [UIColor greenColor];
[self.view addSubview:coustomView];
//開(kāi)始動(dòng)畫(huà)(id用來(lái)區(qū)分多個(gè)動(dòng)畫(huà))
[UIView beginAnimations:@"動(dòng)畫(huà)的id" context:@"附加的值"];
//設(shè)置動(dòng)畫(huà)的屬性(設(shè)置動(dòng)畫(huà)的屬性一定要在開(kāi)始動(dòng)畫(huà)和提交動(dòng)畫(huà)之間寫(xiě))
//時(shí)間
[UIView setAnimationDuration:2];
//動(dòng)畫(huà)的次數(shù)
[UIView setAnimationRepeatCount:1];
//(重復(fù)之后回去的漸變效果)
[UIView setAnimationRepeatAutoreverses:YES];
//設(shè)置動(dòng)畫(huà)的延遲時(shí)間
[UIView setAnimationDelay:1.0];
//設(shè)置代理
[UIView setAnimationDelegate:self];
//動(dòng)畫(huà)將要開(kāi)始的時(shí)候執(zhí)行的方法
[UIView setAnimationWillStartSelector:@selector(startAction:context:)];
//動(dòng)畫(huà)結(jié)束的時(shí)候執(zhí)行的方法
[UIView setAnimationDidStopSelector:@selector(stopAction:context:)];
//運(yùn)動(dòng)軌跡
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
//設(shè)置動(dòng)畫(huà)的最終結(jié)果
coustomView.backgroundColor = [UIColor redColor];
//提交動(dòng)畫(huà)
[UIView commitAnimations];
}
//開(kāi)始執(zhí)行的方法
- (void)startAction:(id)sender context:(id)context
{
NSLog(@"%@ %@",sender,context);
}
//結(jié)束執(zhí)行的方法
- (void)stopAction:(id)sender context:(id)context
{
NSLog(@"%@ %@",sender,context);
}
關(guān)鍵幀動(dòng)畫(huà)(可以添加多個(gè)幀完成動(dòng)畫(huà),多個(gè)幀意味著UIView的多個(gè)形態(tài))
__block UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
coustomView.backgroundColor = [UIColor greenColor];
[self.view addSubview:coustomView];
//關(guān)鍵幀動(dòng)畫(huà)
[UIView animateKeyframesWithDuration:5 delay:1 options:UIViewKeyframeAnimationOptionRepeat animations:^{
//加了兩個(gè)關(guān)鍵幀 , startTime是開(kāi)始的時(shí)間,但是關(guān)鍵幀里的時(shí)間都是要乘以總時(shí)間的,也就是第一個(gè)幀的開(kāi)始時(shí)間肯定為0,第二幀的開(kāi)始時(shí)間應(yīng)該是第一幀結(jié)束,relativeDuration是指本幀運(yùn)行的時(shí)間,也就是說(shuō)兩個(gè)幀的運(yùn)行時(shí)間加起來(lái)要等于1
[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.5 animations:^{
coustomView.frame = CGRectMake(300, 300, 50, 50);
}];
[UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{
coustomView.frame = CGRectMake(100, 500, 100, 100);
}];
} completion:^(BOOL finished) {
}];
spring動(dòng)畫(huà)(也就是彈簧效果+動(dòng)畫(huà)曲線)
//彈簧效果+動(dòng)畫(huà)曲線
- (void)springView
{
__block UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];
coustomView.backgroundColor = [UIColor greenColor];
[self.view addSubview:coustomView];
//1.運(yùn)行的時(shí)間 2.延遲 3.彈簧效果0-1(1是不彈) 4.初始速率 5.動(dòng)畫(huà)的模式(枚舉)
[UIView animateWithDuration:2 delay:1 usingSpringWithDamping: 0.1 initialSpringVelocity:12 options:UIViewAnimationOptionRepeat animations:^{
coustomView.frame = CGRectMake(100, 400, 50, 50);
} completion:^(BOOL finished) {
}];
}
CALayer層的動(dòng)畫(huà)(CoreAnimation)
- CoreAnimation是直接作用于layer層的動(dòng)畫(huà)
- 開(kāi)發(fā)步驟:
- 1.首先得有CALayer
- 2.初始化一個(gè)CAAnimation對(duì)象嘱蛋,并設(shè)置一些動(dòng)畫(huà)相關(guān)屬性
- 3.通過(guò)調(diào)用CALayer的addAnimation:forKey:方法,增加CAAnimation對(duì)象到CALayer中盲憎,這樣就能開(kāi)始執(zhí)行動(dòng)畫(huà)了
- 4.通過(guò)調(diào)用CALayer的removeAnimationForKey:方法可以停止CALayer中的動(dòng)畫(huà)
- 隱式動(dòng)畫(huà): 所有的非主層的layer,也就是手動(dòng)創(chuàng)建的layer,都存在隱式動(dòng)畫(huà),當(dāng)對(duì)layer的部分屬性(也就是注釋中帶有Animatable字樣的)進(jìn)行修改時(shí)會(huì)默認(rèn)自動(dòng)產(chǎn)生一些動(dòng)畫(huà)效果
CALayer概述
- 在ios中所有能看見(jiàn)的控件都是UIView,但其實(shí)UIView是不能顯示東西的,完全是因?yàn)閘ayer層的原因,每一個(gè)UIView控件都至少有一個(gè)layer層(主層),主層是系統(tǒng)幫我們創(chuàng)建好的,但是我們可以在UIView上添加其他的layer層
- CALayer顯示原理:當(dāng)UIView需要顯示到屏幕上時(shí),會(huì)調(diào)用drawRect:方法進(jìn)行繪圖,并且會(huì)將所有內(nèi)容繪制在自己的圖層上凄敢,繪圖完畢后,系統(tǒng)會(huì)將圖層拷貝到屏幕上湿痢,于是就完成了UIView的顯示
- CALayer的基本用法
//layer的屬性和動(dòng)畫(huà)(只要被Animatable修飾的屬性都可以動(dòng)畫(huà))
- (void)layer
{
UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[self.view addSubview:coustomView];
//設(shè)置了layer的背景顏色
coustomView.layer.backgroundColor = [UIColor redColor].CGColor;
//設(shè)置layer描邊的顏色
coustomView.layer.borderColor = [UIColor yellowColor].CGColor;
//設(shè)置layer描邊的寬度
coustomView.layer.borderWidth = 10.0f;
//圓角的半徑
coustomView.layer.cornerRadius = 10;
//陰影的顏色
coustomView.layer.shadowColor = [UIColor blackColor].CGColor;
//陰陽(yáng)的偏移量
coustomView.layer.shadowOffset = CGSizeMake(-5, -5);
//陰影的透明度
coustomView.layer.shadowOpacity = 0.5;
//陰影的模糊成都
coustomView.layer.shadowRadius = 3;
[UIView animateWithDuration:2 animations:^{
//旋轉(zhuǎn) 1.旋轉(zhuǎn)的角度 2.x軸是否轉(zhuǎn)(0或1),3.y軸是否轉(zhuǎn)(0或1),4.z軸是否轉(zhuǎn)(0或1)
coustomView.layer.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);
//縮放 1.x縮放的比例 2.y縮放的比例3.z縮放的比例(沒(méi)效果)
coustomView.layer.transform = CATransform3DMakeScale(0, 0, 0);
//平移的距離 1.x平移距離 2.y平移距離 3.z平移距離(沒(méi)效果)
coustomView.layer.transform = CATransform3DMakeTranslation(100, 100, 100);
}];
//給UIView添加額外的layer層
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(0, 0, 100, 100);
layer.backgroundColor = [UIColor cyanColor].CGColor;
[coustomView.layer addSublayer:layer];
}
- CALayer的position和anchorPoint屬性
- position:用來(lái)設(shè)置layer在父層中的位置,以父層的左上角為原點(diǎn)(0,0)
- anchorPoint:稱為錨點(diǎn),是layer上的哪個(gè)點(diǎn)在position屬性所指的位置顯示,范圍是(0,0)- (1,1),默認(rèn)是(0.5,0.5)
- 例如:position設(shè)置為(0,0),錨點(diǎn)不設(shè)置,也就是說(shuō)layer的中心會(huì)放到(0,0)點(diǎn),layer只顯示了layer的1/4(右下角)
- (void)layerbuchong
{
UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[self.view addSubview:coustomView];
CALayer *layer = [[CALayer alloc] init];
//layer的位置相對(duì)于錨點(diǎn)的
layer.position = CGPointMake(0, 0);
//錨點(diǎn),默認(rèn)0.5,0.5;
layer.anchorPoint =CGPointMake(0, 0);
layer.backgroundColor = [UIColor yellowColor].CGColor;
layer.frame = CGRectMake(0, 0, 100, 100);
[coustomView.layer addSublayer:layer];
}
轉(zhuǎn)場(chǎng)動(dòng)畫(huà)
- 為layer層提供進(jìn)入屏幕和移出屏幕的動(dòng)畫(huà)效果
- 重要屬性:
- type:動(dòng)畫(huà)過(guò)渡類型
- subtype:動(dòng)畫(huà)過(guò)渡方向
- startProgress:動(dòng)畫(huà)起點(diǎn)(在整體動(dòng)畫(huà)的百分比)
- endProgress:動(dòng)畫(huà)終點(diǎn)(在整體動(dòng)畫(huà)的百分比)
- 系統(tǒng)給出的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的type的樣式
2.png
static int i = 2;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// 轉(zhuǎn)場(chǎng)代碼
if (i == 4) {
i = 1;
}
// 加載圖片名稱
NSString *imageN = [NSString stringWithFormat:@"%d",i];
_imageView.image = [UIImage imageNamed:imageN];
i++;
// 轉(zhuǎn)場(chǎng)動(dòng)畫(huà)(一定要和想要轉(zhuǎn)場(chǎng)的代碼放到一起)
CATransition *anim = [CATransition animation];
//動(dòng)畫(huà)過(guò)度的樣式
anim.type = @"pageCurl";
//時(shí)間
anim.duration = 2;
//添加動(dòng)畫(huà)
[_imageView.layer addAnimation:anim forKey:nil];
}
方法 | 說(shuō)明 |
---|---|
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion; | 使用UIView動(dòng)畫(huà)函數(shù)實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫(huà)——單視圖 duration:動(dòng)畫(huà)的持續(xù)時(shí)間 view:需要進(jìn)行轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的視圖 options:轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的類型 animations:將改變視圖屬性的代碼放在這個(gè)block中 completion:動(dòng)畫(huà)結(jié)束后涝缝,會(huì)自動(dòng)調(diào)用這個(gè)block |
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion; | 使用UIView動(dòng)畫(huà)函數(shù)實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫(huà)——雙視圖 duration:動(dòng)畫(huà)的持續(xù)時(shí)間 options:轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的類型 animations:將改變視圖屬性的代碼放在這個(gè)block中 completion:動(dòng)畫(huà)結(jié)束后,會(huì)自動(dòng)調(diào)用這個(gè)block |
CABaseAnimation
- 基礎(chǔ)動(dòng)畫(huà),通過(guò)設(shè)置keypath模仿KVC的形式去改變layer的某個(gè)屬性,但是一次只能修改一個(gè)
- 動(dòng)畫(huà)過(guò)程:隨著動(dòng)畫(huà)的進(jìn)行譬重,在長(zhǎng)度為duration的持續(xù)時(shí)間內(nèi)拒逮,keyPath相應(yīng)屬性的值從fromValue漸漸的變?yōu)閠oValuekeyPath內(nèi)容是CALayer的可動(dòng)畫(huà)Animatable屬性如果fillMode=kCAFillModeForwards同時(shí)removedOnComletion=NO,那么在動(dòng)畫(huà)執(zhí)行完畢后臀规,圖層會(huì)保持顯示動(dòng)畫(huà)執(zhí)行后的狀態(tài)滩援。但在實(shí)質(zhì)上,圖層的屬性值還是動(dòng)畫(huà)執(zhí)行前的初始值塔嬉,并沒(méi)有真正被改變狠怨。
- (void)baseAnimation
{
UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
coustomView.backgroundColor = [UIColor redColor];
//設(shè)置錨點(diǎn)
coustomView.layer.anchorPoint = CGPointMake(0, 0);
[self.view addSubview:coustomView];
//創(chuàng)建CABasicAnimation
CABasicAnimation *baseAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
//初始值(屬性的最初值)
baseAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
//結(jié)束值(絕對(duì)的)
// baseAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(20, 20)];
//結(jié)束值(相對(duì)的)
baseAnimation.byValue = [NSValue valueWithCGPoint:CGPointMake(- 80, - 80)];
//時(shí)間
baseAnimation.duration = 2.0;
//最終的位置
coustomView.layer.position = CGPointMake(20, 20);
//為layer層添加動(dòng)畫(huà),后面的key可以傳空,沒(méi)用
[coustomView.layer addAnimation:baseAnimation forKey:@"1"];
}
CAKeyframeAnimation
- 關(guān)鍵幀動(dòng)畫(huà),與UIView的關(guān)鍵幀動(dòng)畫(huà)模式一樣,但也是通過(guò)基礎(chǔ)動(dòng)畫(huà)的方式改變layer的某個(gè)屬性
- 主要屬性的說(shuō)明:
- values:上述的NSArray對(duì)象。里面的元素稱為“關(guān)鍵幀”(keyframe)邑遏。動(dòng)畫(huà)對(duì)象會(huì)在指定的時(shí)間(duration)內(nèi)佣赖,依次顯示values數(shù)組中的每一個(gè)關(guān)鍵幀
- path:可以設(shè)置一個(gè)CGPathRef、CGMutablePathRef记盒,讓圖層按照路徑軌跡移動(dòng)憎蛤。path只對(duì)CALayer的anchorPoint和position起作用。如果設(shè)置了path纪吮,那么values將被忽略
- keyTimes:可以為對(duì)應(yīng)的關(guān)鍵幀指定對(duì)應(yīng)的時(shí)間點(diǎn)俩檬,其取值范圍為0到1.0,keyTimes中的每一個(gè)時(shí)間值都對(duì)應(yīng)values中的每一幀碾盟。如果沒(méi)有設(shè)置keyTimes棚辽,各個(gè)關(guān)鍵幀的時(shí)間是平分的
- CABasicAnimation可看做是只有2個(gè)關(guān)鍵幀的CAKeyframeAnimation
//關(guān)鍵幀動(dòng)畫(huà)
- (void)CAKeyframeAnimation
{
UIView *coustomView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
coustomView.backgroundColor = [UIColor redColor];
coustomView.layer.anchorPoint = CGPointMake(0, 0);
[self.view addSubview:coustomView];
//關(guān)鍵幀動(dòng)畫(huà)
CAKeyframeAnimation *key = [CAKeyframeAnimation animationWithKeyPath:@"position"];
CGPoint point1 = CGPointMake(40,0);
CGPoint point2 = CGPointMake(80,0);
CGPoint point3 = CGPointMake(80,40);
CGPoint point4 = CGPointMake(80,80);
//關(guān)鍵幀的值
key.values = @[[NSValue valueWithCGPoint:point1],[NSValue valueWithCGPoint:point2],[NSValue valueWithCGPoint:point3],[NSValue valueWithCGPoint:point4]];
//添加時(shí)間
key.duration = 10;
//設(shè)置每一幀的運(yùn)行時(shí)間
key.keyTimes = @[@(0.7),@(0.1),@(0.1)];
coustomView.layer.position = CGPointMake(80, 80);
//添加動(dòng)畫(huà)
[coustomView.layer addAnimation:key forKey:@"1"];
}