iOS动画学习

时间:2023-03-08 18:12:07

学习一下动画,感谢以下大神的文章:
    UIView:基础动画.关键帧动画.转场动画

Core Animation :基础动画,关键帧动画,动画组,转场动画,逐帧动画

CALayer :CALayer简介,CALayer常用属性,CALayer绘图

===>        http://www.cnblogs.com/kenshincui/p/3972100.html

Quartz 2D

Swift3.0 一些动画基础整理

iOS-仿膜拜贴纸滚动(物理仿真)

iOS那些简单的动画(不定期更新

 iOS动画篇_CALayer这些牛逼的子类你造吗

在看完这些文章之后,本猿照葫芦画猴子,写了个小demo,算是简单学习下动画.该demo中使用CABasicAnimation CAKeyframeAnimation keyframeAnimation

贝塞尔曲线绘制路径 UIView动画 逐帧动画 UIView动画 转场动画 动画组 CALayer动画,传感器仿膜拜动画大锅乱炖.

1.首先为各个动画写个入口

 - (void)viewDidLoad {
[super viewDidLoad];
//背景
UIImage * bgImg = [UIImage imageNamed:@"树林"];
self.bgImg = [[UIImageView alloc]initWithFrame:CGRectMake(, , SCRCCEWH.width, SCRCCEWH.height)];
self.bgImg.image = bgImg;
[self.view addSubview:self.bgImg]; self.currentIndex = ; //默认第一张图片
self.ballAry = @[@"大师球",@"高级球",@"超级球",@"精灵球"]; //先准备4个球体 //晴天娃娃摇摆动画
[self sunChildAniamtion]; //基础动画 CABasicAnimation
//制作树叶layer
[self makeLeafLayer];
//制作小汽车
[self makeCarLayer];
//落叶下落动画
[self fallLeafAnimation]; //关键帧动画 CAKeyframeAnimation 通过贝塞尔曲线绘制下路路径 CGPathCreateMutable
//落叶旋转动画
[self leafOverturnAnimation]; //基础动画 CABasicAnimation
//落叶生长动画
[self leafGrowAnimation]; //UIView动画
//蝴蝶飞舞动画
[self butterflyAnimation]; //逐帧动画:振翅 飞翔:关键帧动画 路径:keyframeAnimation }

2.点击屏幕的时候,展开转场动画(水波效果),仿膜拜动画,组合动画(汽车动画)

 //MARK:点击屏幕
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//制作球体
WLBallView * ballView = [[WLBallView alloc] initWithFrame:CGRectMake(, , , ) AndImageName:self.ballAry[arc4random_uniform()]];
[self.view addSubview:ballView];
[ballView starMotion];
//系统转场动画
CATransition *transition = [CATransition animation];
transition.type = @"rippleEffect"; //部分动画类型是未公开的,但仍然可以使用
transition.duration = ;
[self.bgImg.layer addAnimation:transition forKey:nil];
//组合动画
[self groupAnimation]; //组合动画(汽车)
}

3.接下来是组合动画(汽车)的代码,组合CABasicAnimation + CAKeyframeAnimation

 //MARK:制作小汽车
-(void)makeCarLayer{
self.carLayer = [[CALayer alloc]init];
self.carLayer.bounds = CGRectMake(, , , );
self.carLayer.position = CGPointMake(SCRCCEWH.width - , SCRCCEWH.height - );
self.carLayer.contents = (id)[UIImage imageNamed:@"小汽车"].CGImage;
[self.view.layer addSublayer:self.carLayer];
}
//MARK:组合动画
-(void)groupAnimation{
// 1.创建动画组
CAAnimationGroup * animationGroup = [CAAnimationGroup animation];
// 2.设置组中的动画和其他属性
CABasicAnimation * basicAnimation = [self carBasicAnimation];
CAKeyframeAnimation * keyframeAnimation = [self carKeyFrameAnimation];
animationGroup.animations = @[keyframeAnimation,basicAnimation]; animationGroup.duration=10.0;//设置动画时间,如果动画组中动画已经设置过动画属性则不再生效
animationGroup.beginTime=CACurrentMediaTime()+;//延迟五秒执行 //3.给图层添加动画
[self.carLayer addAnimation:animationGroup forKey:nil];
}
//小汽车加速动画
-(CABasicAnimation *)carBasicAnimation{
CABasicAnimation *basicAnimation=[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; CGFloat toValue= M_PI_2 / 2.5;
basicAnimation.toValue=[NSNumber numberWithFloat: M_PI_2/2.5];
[basicAnimation setValue:[NSNumber numberWithFloat:toValue] forKey:@"carTransform"];
return basicAnimation;
}
//MARK:小汽车移动动画
-(CAKeyframeAnimation *)carKeyFrameAnimation{
CAKeyframeAnimation *keyframeAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"]; CGPoint endPoint= CGPointMake(-, SCRCCEWH.height - );
CGPathRef path=CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, self.carLayer.position.x, self.carLayer.position.y);
CGPathAddCurveToPoint(path, NULL, endPoint.x/, endPoint.y, endPoint.x/, endPoint.y, endPoint.x, endPoint.y); keyframeAnimation.path=path;
CGPathRelease(path); [keyframeAnimation setValue:[NSValue valueWithCGPoint:endPoint] forKey:@"carRunAnimation"]; return keyframeAnimation;
}

4.落叶动画.落叶通过CALayer绘制,UIVIew动画控制叶子生长动画,叶子下落动画通过关键帧动画.路径通过绘制二次贝塞尔曲线,叶子旋转动画通过基础动画CABasicAnimation

 /*---------------------------------------------------------------------------------------*/
//MARK:制作落叶Layer
-(void)makeLeafLayer{
self.leafLayer = [[CALayer alloc]init];
self.leafLayer.bounds = CGRectMake(, , , );
self.leafLayer.position = CGPointMake(, );
self.leafLayer.anchorPoint = CGPointMake(0.5, 0.6); //锚点,便于旋转动画
self.leafLayer.contents = (id)[UIImage imageNamed:@"落叶"].CGImage;
[self.view.layer addSublayer:self.leafLayer];
}
//MARK:落叶生长动画
-(void)leafGrowAnimation{
UIImageView * imgView = [[UIImageView alloc]initWithFrame:CGRectMake(, , , )];
imgView.image = [UIImage imageNamed:@"落叶"];
imgView.layer.position = CGPointMake(, );
[self.view addSubview:imgView]; [UIView animateWithDuration:8.5 animations:^{
imgView.frame = CGRectMake(, , , );
imgView.layer.position = CGPointMake(, );
} completion:^(BOOL finished) {
[imgView removeFromSuperview];
[self leafGrowAnimation];
}]; }
//MARK: 落叶下落动画
-(void)fallLeafAnimation{
//1.创建关键帧动画并设置动画属性
CAKeyframeAnimation *keyframeAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"]; //2.设置路径
//绘制贝塞尔曲线
CGPathRef path=CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, self.leafLayer.position.x, self.leafLayer.position.y);//移动到起始点
CGPathAddCurveToPoint(path, NULL, , , -, , ,SCRCCEWH.height);//绘制二次贝塞尔曲线 keyframeAnimation.path=path;//设置path属性
CGPathRelease(path);//释放路径对象
keyframeAnimation.repeatCount = HUGE_VALF; //重复次数
keyframeAnimation.calculationMode = kCAAnimationCubicPaced; //动画的计算模式
keyframeAnimation.keyTimes = @[@0.0,@0.5,@0.7,@1.0]; //控制各个帧的时间
//设置其他属性
keyframeAnimation.duration=8.0;
keyframeAnimation.beginTime=CACurrentMediaTime()+;//设置延迟执行 //3.添加动画到图层,添加动画后就会执行动画
[self.leafLayer addAnimation:keyframeAnimation forKey:@"fallLeaf"];
}
//MARK:落叶旋转动画
-(void)leafOverturnAnimation{
// 1.创建动画并制定动画属性
CABasicAnimation * basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
// 2.设置动画属性结束值
basicAnimation.toValue = [NSNumber numberWithFloat:M_PI_2*];
basicAnimation.repeatCount = HUGE_VALF;
// 3.设置动画属性的属性
basicAnimation.duration = 6.0;
basicAnimation.autoreverses = YES; //旋转后再旋转回原来的位置 // 4.添加动画到图层,注意key仅仅相当于给动画命名,以后获取动画可以采用该名字获取
[self.leafLayer addAnimation:basicAnimation forKey:@"leafOverturn"];
}

4.娃娃摇摆动画,通过基础动画CABasicAnimation

 //MARK: 晴天娃娃摇摆动画
-(void)sunChildAniamtion{
UIImageView * imgView = [[UIImageView alloc]initWithFrame:CGRectMake(, , , )];
imgView.center = CGPointMake(SCRCCEWH.width/, );
imgView.image = [UIImage imageNamed:@"娃娃"];
imgView.layer.anchorPoint = CGPointMake(28.5/, /);
[self.view addSubview:imgView]; id fromValue = [NSNumber numberWithFloat:-M_PI/ 10.0];
id toValue = [NSNumber numberWithFloat:M_PI/ 10.0];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.duration = 1.5; // 持续时间 CAMediaTimingFunction *mediaTiming = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.timingFunction = mediaTiming;
animation.repeatCount = HUGE_VALF; // 重复次数
animation.fromValue = fromValue;// 起始角度
animation.toValue = toValue; // 终止角度
animation.autoreverses = YES;
[imgView.layer addAnimation:animation forKey:nil];
}

5.蝴蝶动画,震翅通过逐帧动画,路径通过关键帧动画的属性,设置关键帧实现

 //得到蝴蝶当前图片
- (UIImage *)getImage:(BOOL)isNext{
if(isNext){
self.currentIndex = (self.currentIndex + )%IMAGE_COUNT;
}else{
self.currentIndex = (self.currentIndex - + IMAGE_COUNT)%IMAGE_COUNT;
}
NSString * imageName = [NSString stringWithFormat:@"%i.jpg",self.currentIndex];
return [UIImage imageNamed:imageName];
}
//蝴蝶飞舞动画
-(void)butterflyAnimation{
self.butterflyLayer = [[CALayer alloc]init];
self.butterflyLayer.bounds = CGRectMake(, , , );
self.butterflyLayer.position = CGPointMake(SCRCCEWH.width, SCRCCEWH.height/);
[self.view.layer addSublayer:self.butterflyLayer]; self.images = [NSMutableArray array];
for (int i = ; i <= ; i++){
NSString * imageName = [NSString stringWithFormat:@"fly%i.png",i];
UIImage * image = [UIImage imageNamed:imageName];
[self.images addObject:image];
} // 定义时钟对象
CADisplayLink * displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(step)];
// 添加时钟对象到主队列循环
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; // 蝴蝶飞舞路径
[self butterflypath];
}
//MARK:蝴蝶飞舞路径
-(void)butterflypath{
//1.创建关键帧动画并设置动画属性
CAKeyframeAnimation *keyframeAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"]; //2.设置关键帧
NSValue * key1 = [NSValue valueWithCGPoint:self.butterflyLayer.position]; //对于关键帧动画初始值不能省略
NSValue * key2 = [NSValue valueWithCGPoint:CGPointMake(, )];
NSValue * key3 = [NSValue valueWithCGPoint:CGPointMake(, )];
NSValue * key4 = [NSValue valueWithCGPoint:CGPointMake(, )];
NSValue * key5 = [NSValue valueWithCGPoint:CGPointMake(, )];
NSArray * values = @[key1,key2,key3,key4,key5];
keyframeAnimation.values = values; keyframeAnimation.repeatCount = HUGE_VALF; //重复次数
keyframeAnimation.calculationMode = kCAAnimationCubicPaced; //动画的计算模式
keyframeAnimation.keyTimes = @[@0.0,@0.5,@0.7,@1.0]; //控制各个帧的时间
//设置其他属性
keyframeAnimation.duration=;
keyframeAnimation.beginTime=CACurrentMediaTime()+;//设置延迟执行
//3.添加动画到图层,添加动画后就会执行动画
[self.butterflyLayer addAnimation:keyframeAnimation forKey:@"butterfly"]; }
//MARK: 每次屏幕刷新就会执行一次此方法
-(void)step{
//定义一个变量记录执行次数
static int s = ;
if(++s % == ){
UIImage * image = self.images[self.currentIndex];
self.butterflyLayer.contents = (id)image.CGImage;
self.currentIndex = (self.currentIndex + )%IMAGE_COUNT;
} }

iOS动画学习

github源代码: https://github.com/pheromone/iOSAnimationLearn