CAAnimation 是所有动画对象的父类 负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类
子类分为下面4种:
1、CABasicAnimation :通过设定起始点,终点,时间,动画会沿着你这设定点进行移动。可以看做特殊的CAKeyFrameAnimation
2、CAKeyframeAnimation Keyframe顾名思义就是关键点的frame,你可以通过设定CALayer的始点、中间关键点、终点的frame,时间,动画会沿你设定的轨迹进行移动
3、CAAnimationGroup Group也就是组合的意思,就是把对这个Layer的所有动画都组合起来。PS:一个layer设定了很多动画,他们都会同时执行。
4、CATransition 这个就是苹果帮开发者封装好的一些动画
CAAnimation 属性说明
1、duration:动画的持续时间
2、repeatCount:重复次数,无线循环可以设置HUGE_VALF或者MAXFLOAT 我一般喜欢用后面的这个
3、repeatDuration:重复时间
4、removeedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。
如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode为kCAFillModeForwands.
CAAnimation 动画填充模式
*fillMode属性值(要想fillMode有效,最好设置removedOnCompletion = NO);
1、kCAFillModeRemoved这个是默认值,也就是说当动画开始前和动画结束后,动画对
layer都没有影响,动画结束后,layer会恢复到之前的状态
2、kCAFillModeForwards当动画结束后,layer会⼀一直保持着动画最后的状态
3、kCAFillModeBackwards在动画开始前,只需要将动画加⼊入了⼀一个layer,layer便⽴立即进⼊入动画的初始状态并等待动画开始。
4、kCAFillModeBoth这个其实就是上⾯面两个的合成.动画加⼊入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态
CAAnimation 速度控制函数(CAMediaTimeingFunction)
1、KCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉
2、KCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开
3、KCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速到达目的地
4、KCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速到达目的地。这个是默认的动画行为。
CATransition-------转场动画 是CAANimation的子类,用于做转场动画,能够为层提供移出屏幕,移入屏幕的动画效果。
UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果。
动画属性:
1、type:动画过渡类型
2、subtype:动画过渡方向
3、startProgress:动画起点(在整体动画的百分比)
4、endProgress:动画终点(在整体动画的百分比)
转场动画过渡效果,如下图
使用UIVIew动画函数实现转场动画 ---- 单视图
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options: (UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;
参数说明
1、duration:动画的持续时间
2、view:需要进行转场动画的视图
3、options:转场动画的类型
4、animations:将改变视图属性的代码放在block中
5、completion:动画结束后。会自动调用这个block
使用UIVIew动画函数实现转场动画 ---- 双视图
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:
(NSTimeInterval)duration options:
(UIViewAnimationOptions)options completion:(void
(^)(BOOL finished))completion;
参数说明跟上面类似 这个方法调用完毕,相当于执行了下面两句代码:
// 添加toView到⽗父视图
[fromView.superview addSubview:toView];
// 把fromView从⽗父视图中移除
[fromView.superview removeFromSuperview];
转场动画存在的问题
动画过程中无法交互。如果在切换时实现交互效果需要使用 UIScrollView + UIpageControl
/*************不多扯了 上面做个笔记 下面贴代码 CAAnimation ********/
我全贴了吧 可以直接运行 Demo1
//
// ViewController.m
// Animation
//
// Created by lxy on 15/8/20.
// Copyright (c) 2015年 Shenzhen *** Technology Co.,LTD. All rights reserved.
//
#import "ViewController.h"
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
@interface ViewController ()
@property (nonatomic , strong) UIView *demoView;
@property (nonatomic,strong) UIView *circleView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self initUI];
}
- (void)initUI
{
_demoView = [[UIView alloc] initWithFrame:CGRectMake(SCREEN_WIDTH/2-50, SCREEN_HEIGHT/2-100,50 ,50 )];
_demoView.backgroundColor = [UIColor redColor];
[self.view addSubview:_demoView];
NSArray *array = [NSArray arrayWithObjects:@"位移",@"透明度",@"缩放",@"旋转",@"背景色", nil];
NSArray *array1 = [NSArray arrayWithObjects:@"关键帧",@"路径",@"抖动",@"同时",@"连续", nil];
for ( int i = 0; i<array.count; i++) {
UIButton *btn = [[UIButton alloc]init];
[btn setTitle:array[i] forState:UIControlStateNormal];
[btn setBackgroundColor:[UIColor lightGrayColor]];
btn.tag = i;
btn.frame = CGRectMake(10+60*i, SCREEN_HEIGHT -130, 50, 25);
btn.titleLabel.font = [UIFont systemFontOfSize:13];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
UIButton *btn1 = [[UIButton alloc]init];
[btn1 setTitle:array1[i] forState:UIControlStateNormal];
[btn1 setBackgroundColor:[UIColor lightGrayColor]];
btn1.tag = i+10;
btn1.frame = CGRectMake(10+60*i, SCREEN_HEIGHT -100, 50, 25);
btn1.titleLabel.font = [UIFont systemFontOfSize:13];
[btn1 addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn1];
}
_circleView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 20, 20)];
_circleView.center = CGPointMake(100, 40);
//这样就形成一个园 因为width是20 所以圆心到哪都是10
_circleView.layer.cornerRadius = self.circleView.frame.size.width/2;
_circleView.backgroundColor = [UIColor redColor];
[self.view addSubview:_circleView];
// UIView *secView = [[UIView alloc]init];
// secView.frame = CGRectMake(130, 30, 20, 20);
// secView.backgroundColor = [UIColor cyanColor];
// secView.layer.cornerRadius = 6;
// [self.view addSubview:secView];
}
- (void)btnClick:(UIButton *)btn
{
switch (btn.tag) {
case 0:
[self positionAnimation];
[self circleRun];
break;
case 1:
[self opacityAniamtion];
break;
case 2:
[self scaleAnimation];
break;
case 3:
[self rotateAnimation];
break;
case 4:
[self backgroundAnimation];
break;
case 10:
[self keyFrameAnimation];
break;
case 11:
[self pathAnimation];
break;
case 12:
[self shakeAnimation];
break;
case 13:
[self groupAnimation1];
break;
case 14:
[self groupAnimation2];
break;
default:
break;
}
}
- (void)circleRun{
[UIView animateWithDuration:3 animations:^{
self.circleView.center = CGPointMake(100, self.view.frame.size.height-10);
} completion:^(BOOL finished) {
[UIView animateWithDuration:3 animations:^{
self.circleView.center = CGPointMake(100, 40);
}];
}];
}
/**
* 位移动画演示
*/
-(void)positionAnimation{
CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"position"];
anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)];
anima.toValue = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-75)];
anima.duration = 3.0f;
//如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。
anima.fillMode = kCAFillModeForwards;
// anima.removedOnCompletion = NO;
[_demoView.layer addAnimation:anima forKey:@"positionAnimation"];
}
/**
* 透明度动画
*/
-(void)opacityAniamtion{
CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"opacity"];
anima.fromValue = [NSNumber numberWithFloat:1.0f];
anima.toValue = [NSNumber numberWithFloat:0.2f];
anima.duration = 1.0f;
[_demoView.layer addAnimation:anima forKey:@"opacityAniamtion"];
}
/**
* 缩放动画
*/
-(void)scaleAnimation{
// CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"bounds"];
// anima.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 200, 200)];
// anima.duration = 1.0f;
// [_demoView.layer addAnimation:anima forKey:@"scaleAnimation"];
CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"transform.scale"];//同上
anima.toValue = [NSNumber numberWithFloat:2.0f];
anima.duration = 1.0f;
[_demoView.layer addAnimation:anima forKey:@"scaleAnimation"];
// CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"transform.scale.x"];
// anima.toValue = [NSNumber numberWithFloat:0.2f];
// anima.duration = 1.0f;
// [_demoView.layer addAnimation:anima forKey:@"scaleAnimation"];
}
/**
* 旋转动画
*/
-(void)rotateAnimation{
CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];//绕着z轴为矢量,进行旋转(@"transform.rotation.z"==@@"transform.rotation")
anima.toValue = [NSNumber numberWithFloat:M_PI];
anima.duration = 1.0f;
[_demoView.layer addAnimation:anima forKey:@"rotateAnimation"];
// //valueWithCATransform3D作用与layer
// CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"transform"];
// anima.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 0, 0, 1)];//绕着矢量(x,y,z)旋转
// anima.duration = 1.0f;
// //anima.repeatCount = MAXFLOAT;
// [_demoView.layer addAnimation:anima forKey:@"rotateAnimation"];
// //CGAffineTransform作用与View
// _demoView.transform = CGAffineTransformMakeRotation(0);
// [UIView animateWithDuration:1.0f animations:^{
// _demoView.transform = CGAffineTransformMakeRotation(M_PI);
// } completion:^(BOOL finished) {
//
// }];
}
/**
* 背景色变化动画
*/
-(void)backgroundAnimation{
CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
anima.toValue =(id) [UIColor greenColor].CGColor;
anima.duration = 1.0f;
[_demoView.layer addAnimation:anima forKey:@"backgroundAnimation"];
}
/**
* 关键帧动画
*/
-(void)keyFrameAnimation{
CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"];
NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)];
NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)];
NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)];
NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)];
NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)];
NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50)];
anima.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];
anima.duration = 2.0f;
anima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];//设置动画的节奏
anima.delegate = self;//设置代理,可以检测动画的开始和结束
[_demoView.layer addAnimation:anima forKey:@"keyFrameAnimation"];
}
-(void)animationDidStart:(CAAnimation *)anim{
NSLog(@"开始动画");
}
-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
NSLog(@"结束动画");
}
/**
* path动画
*/
-(void)pathAnimation{
CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"];
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2-100, 200, 200)];
anima.path = path.CGPath;
anima.duration = 2.0f;
[_demoView.layer addAnimation:anima forKey:@"pathAnimation"];
}
/**
* 抖动效果
*/
-(void)shakeAnimation{
CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];//在这里@"transform.rotation"==@"transform.rotation.z"
NSValue *value1 = [NSNumber numberWithFloat:-M_PI/180*4];
NSValue *value2 = [NSNumber numberWithFloat:M_PI/180*4];
NSValue *value3 = [NSNumber numberWithFloat:-M_PI/180*4];
anima.values = @[value1,value2,value3];
anima.repeatCount = MAXFLOAT;
[_demoView.layer addAnimation:anima forKey:@"shakeAnimation"];
}
-(void)groupAnimation1{
//位移动画
CAKeyframeAnimation *anima1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)];
NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)];
NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)];
NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)];
NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)];
NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50)];
anima1.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];
//缩放动画
CABasicAnimation *anima2 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
anima2.fromValue = [NSNumber numberWithFloat:0.2f];
anima2.toValue = [NSNumber numberWithFloat:1.0f];
//旋转动画
CABasicAnimation *anima3 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
anima3.toValue = [NSNumber numberWithFloat:M_PI*12];
//组动画
CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
groupAnimation.animations = [NSArray arrayWithObjects:anima1,anima2,anima3, nil];
groupAnimation.duration = 4.0f;
[_demoView.layer addAnimation:groupAnimation forKey:@"groupAnimation"];
//-------------如下,使用三个animation不分装成group,只是把他们添加到layer,也有组动画的效果。-------------
// //位移动画
// CAKeyframeAnimation *anima1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
// NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)];
// NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)];
// NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)];
// NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)];
// NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)];
// NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50)];
// anima1.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil];
// anima1.duration = 4.0f;
// [_demoView.layer addAnimation:anima1 forKey:@"aa"];
//
// //缩放动画
// CABasicAnimation *anima2 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
// anima2.fromValue = [NSNumber numberWithFloat:0.8f];
// anima2.toValue = [NSNumber numberWithFloat:2.0f];
// anima2.duration = 4.0f;
// [_demoView.layer addAnimation:anima2 forKey:@"bb"];
//
// //旋转动画
// CABasicAnimation *anima3 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
// anima3.toValue = [NSNumber numberWithFloat:M_PI*4];
// anima3.duration = 4.0f;
// [_demoView.layer addAnimation:anima3 forKey:@"cc"];
}
/**
* 顺序执行的组动画
*/
-(void)groupAnimation2{
CFTimeInterval currentTime = CACurrentMediaTime();
//位移动画
CABasicAnimation *anima1 = [CABasicAnimation animationWithKeyPath:@"position"];
anima1.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-75)];
anima1.toValue = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/2, SCREEN_HEIGHT/2-75)];
anima1.beginTime = currentTime;
anima1.duration = 1.0f;
anima1.fillMode = kCAFillModeForwards;
anima1.removedOnCompletion = NO;
[_demoView.layer addAnimation:anima1 forKey:@"aa"];
//缩放动画
CABasicAnimation *anima2 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
anima2.fromValue = [NSNumber numberWithFloat:0.8f];
anima2.toValue = [NSNumber numberWithFloat:2.0f];
anima2.beginTime = currentTime+1.0f;
anima2.duration = 1.0f;
anima2.fillMode = kCAFillModeForwards;
anima2.removedOnCompletion = NO;
[_demoView.layer addAnimation:anima2 forKey:@"bb"];
//旋转动画
CABasicAnimation *anima3 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
anima3.toValue = [NSNumber numberWithFloat:M_PI*4];
anima3.beginTime = currentTime+2.0f;
anima3.duration = 1.0f;
anima3.fillMode = kCAFillModeForwards;
anima3.removedOnCompletion = NO;
[_demoView.layer addAnimation:anima3 forKey:@"cc"];
}
@end
Demo2
//
// ViewController.m
// UIViewText
//
// Created by msd on 14-12-2.
// Copyright (c) 2014年 ***. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor cyanColor];
[self addView];
[self addView1];
}
- (void)addView
{
for (int i=0; i<4; i++) {
UIButton *btn = [[UIButton alloc]init];
btn.frame = CGRectMake(10, 50+50*i, 300, 50);
btn.backgroundColor = [UIColor magentaColor];
[btn setTitle:[NSString stringWithFormat:@"hello%d",i] forState:UIControlStateNormal];
btn.tag = i;
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
UIView *view = [[UIView alloc]init];
view.frame = CGRectMake(10, 50+50*i, 300, 1);
view.backgroundColor = [UIColor grayColor];
[self.view addSubview:btn];
[self.view addSubview:view];
}
}
- (void)addView1
{
for (int i=0; i<5; i++) {
UIButton *btn = [[UIButton alloc]init];
btn.frame = CGRectMake(10,270+50*i, 300, 50);
btn.backgroundColor = [UIColor lightTextColor];
[btn setTitle:[NSString stringWithFormat:@"hello%d",i] forState:UIControlStateNormal];
btn.tag = i+4;
[btn addTarget:self action:@selector(btnTouchUp:) forControlEvents:UIControlEventTouchUpInside];
UIView *view = [[UIView alloc]init];
view.frame = CGRectMake(10, 270+50*i, 300, 1);
view.backgroundColor = [UIColor grayColor];
[self.view addSubview:btn];
[self.view addSubview:view];
}
}
- (void)btnClick:(UIButton *)b
{
[UIView beginAnimations:@"animationID" context:nil];
[UIView setAnimationDuration:0.5f];
// [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationRepeatAutoreverses:YES];
UIButton *btn = (UIButton *)b;
switch (btn.tag) {
case 0:
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES];
break;
case 1:
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
break;
case 2:
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
break;
case 3:
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view cache:YES];
break;
default:
break;
}
[self.view exchangeSubviewAtIndex:1 withSubviewAtIndex:0];
[UIView commitAnimations];
}
- (void)btnTouchUp:(UIButton *)b
{
CATransition *animation = [CATransition animation];
//animation.delegate = self;
animation.duration = 1.2f;
animation.timingFunction = UIViewAnimationCurveEaseInOut;
animation.fillMode = kCAFillModeForwards;
UIButton *theButton = (UIButton *)b;
/*
kCATransitionFade;
kCATransitionMoveIn;
kCATransitionPush;
kCATransitionReveal;
*/
/*
kCATransitionFromRight;
kCATransitionFromLeft;
kCATransitionFromTop;
kCATransitionFromBottom;
*/
switch (theButton.tag) {
case 4:
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromTop;
break;
case 5:
animation.type = kCATransitionMoveIn;
animation.subtype = kCATransitionFromTop;
break;
case 6:
animation.type = kCATransitionReveal;
animation.subtype = kCATransitionFromTop;
break;
case 7:
animation.type = kCATransitionFade;
animation.subtype = kCATransitionFromTop;
break;
case 8:
animation.type = @"rippleEffect";//110
break;
default:
break;
}
[self.view.layer addAnimation:animation forKey:@"animation"];
}
@end