常用动画,iOS动画集锦

2019-09-11 12:59 来源:未知

最近写项目发现越来越没动力了,

iOS 动画主要是指 Core Animation 框架, Core AnimationiOSOS X 平台上负责图形渲染与动画的基础框架。Core Animation 可以作用于动画视图或者其他可视元素,可以完成动画所需的大部分绘帧工作。Core Animation 系统已经进行了封装, 所以在使用的时候你只需要配置少量的动画参数(如开始点的位置和结束点的位置)即可使用 Core Animation 的多种动画效果。Core Animation 将大部分实际的绘图任务交给了图形硬件(GPU)来处理,图形硬件会加速图形渲染的速度。这种自动化的图形加速技术让动画拥有更高的帧率并且显示效果更加平滑,不会加重CPU的负担而影响程序的运行速度。

iOS的动画效果一直都很棒很,给人的感觉就是很炫酷很流畅,起到增强用户体验的作用。在APP开发中实现动画效果有很多种方式,对于简单的应用场景,我们可以使用UIKit提供的动画来实现。

底层的东西实在太让人头疼了。。。

本文主要总结下平时常用的动画, 如: 基础动画(CABasicAnimation)、关键帧动画(CAKeyframeAnimation)、组动画(CAAnimationGroup)、过渡动画(CATransition), 最后也扩展了下, 做了进度条、贝塞尔曲线画心❤️、弹球、钉钉效果、点赞等动画,希望对大家有所帮助.github:

UIView动画

UIView动画实质上是对CoreAnimation的封装,iOS4.0以后,增加了Block动画块,提供更简洁的方式来实现动画。

所幸研究一点好玩的东西~~那就是特效!!!

图片 1Core Animation.jpeg

共有六个常见的Block动画方法:
  • 1、最简单的Block动画,包含时间和动画[UIView animateWithDuration:<#(NSTimeInterval)#> animations:<#^animations#>];

  • 2、带有动画完成回调的Block动画 [UIView animateWithDuration:<#(NSTimeInterval)#> animations:<#^animations#> completion:<#^(BOOL finished)completion#>];

  • 3、可设置延迟时间和过渡效果的Block动画 ``[UIView animateWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> options:<#(UIViewAnimationOptions)#> animations:<#^animations#> completion:<#^(BOOL finished)completion#>]

  • 4、Spring动画,iOS7.0后新增Spring动画(iOS系统动画大部分采用SpringAnimation,适用于所有可被添加动画效果的属性)[UIView animateWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> usingSpringWithDamping:<##> initialSpringVelocity:<##> options:<#(UIViewAnimationOptions)#> animations:<#^animations#> completion:<#^(BOOL finished)completion#>]

  • 5、Keyframes动画,iOS7.0后新增关键帧动画,支持属性关键帧,不支持路径关键帧 [UIView animateKeyframesWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> options:<#(UIViewKeyframeAnimationOptions)#> animations:<#^animations#> completion:<#^(BOOL finished)completion#>]

  • 6、转场动画

    • 从旧视图转到新视图的动画效果,在该动画过程中,fromView会从父视图中移除,并讲toView添加到父视图中,注意转场动画的作用对象是父视图(过渡效果体现在父视图上)[UIView transitionFromView:<#(nonnull UIView *)#> toView:<#(nonnull UIView *)#> duration:<#(NSTimeInterval)#> options:<#(UIViewAnimationOptions)#> completion:<#^(BOOL finished)completion#>]
  • 单个视图的过渡效果 [UIView transitionWithView:<#(nonnull UIView *)#> duration:<#(NSTimeInterval)#> options:<#(UIViewAnimationOptions)#> animations:<#^animations#> completion:<#^(BOOL finished)completion#>]

biubiubibuiubiu~~~~~~

  1. 首先通过官方的 Core Animation 类图了解下各个类之间的关系. 官网链接:Core Animation

    图片 2Core Animation.png建议详细看下上图, 这里对 CAAnimation 的子类和相互关系及属性介绍的比较详细, 看完后会对各个动画类型有个大概的了解.

  2. 接下来详细介绍下动画的各个属性及作用

UIView动画可以设置的动画属性有
  • 1、大小变化
  • 2、拉伸变化
  • 3、中心位置变化
  • 4、旋转(transform)
  • 5、透明度
  • 6、背景色(backgroundColor)

transform属性作用:给我们的控件做一些形变,移动

// 平移//每次移动都是相对于上次位置 _redView.transform = CGAffineTransformTranslate(_redView.transform, 100, 0);//每次移动都是相对于最开始的位置 _redView.transform = CGAffineTransformMakeTranslation;

缩放

// sx:宽度缩放的比例 sy:高度缩放的比例//每次缩放都是相对于最初的大小_redView.transform = CGAffineTransformMakeScale;//每次缩放都是相对于上次的大小_redView.transform = CGAffineTransformScale(_redView.transform, 0.5, 0.5);

旋转

// 每次旋转都是相对于最初的角度_redView.transform = CGAffineTransformMakeRotation;//每次旋转都是相对于现在的角度_redView.transform = CGAffineTransformRotate(_redView.transform, M_PI_4);

好了废话不说 开始讲解 各种常见的不常见的甚至没见过的 iOS自带特效!

  • fromValue: 动画的开始值(Any类型, 根据动画不同可以是CGPoint、NSNumber等)
  • toValue: 动画的结束值, 和fromValue类似
  • beginTime: 动画的开始时间
  • duration : 动画的持续时间
  • repeatCount : 动画的重复次数
  • fillMode: 动画的运行场景
  • isRemovedOnCompletion: 完成后是否删除动画
  • autoreverses: 执行的动画按照原动画返回执行
  • path:关键帧动画中的执行路径
  • values: 关键帧动画中的关键点数组
  • animations: 组动画中的动画数组
  • delegate : 动画代理, 封装了动画的执行和结束方法
  • timingFunction: 控制动画的显示节奏, 系统提供五种值选择,分别是:1.kCAMediaTimingFunctionDefault2.kCAMediaTimingFunctionLinear 3.kCAMediaTimingFunctionEaseIn (先慢后快 慢进快出)4.kCAMediaTimingFunctionEaseOut 5.kCAMediaTimingFunctionEaseInEaseOut
  • type: 过渡动画的动画类型,系统提供了多种过渡动画, 分别是:1: fade 2: moveIn 3: push 4: fade 5: reveal 6: cube 7: suck 8: oglFlip 9: ripple 10: curl (卷曲翻页 向上翻页)11: unCurl (卷曲翻页返回 向下翻页)12: caOpen 13: caClose
  • subtype : 过渡动画的动画方向, 系统提供了四种,分别是:1.fromLeft2.fromRight 3.fromTop 4.fromBottom

实战说明

基础动画-位移

图片 3基础动画-位移gif.gif

基础动画主要提供了对于CALayer对象中的可变属性进行简单动画的操作。比如:位移、旋转、缩放、透明度、背景色等。基础动画根据 keyPath 来区分不同的动画,, 系统提供了多个类型,如: transform.scaletransform.scale.xtransform.scale.ytransform.rotationtransform.rotation.xtransform.rotation.ytransform.rotation.zopacitymarginbackgroundColorcornerRadiusborderWidthboundscontentscontentsRectcornerRadiusframehiddenmaskmasksToBoundsshadowColorshadowOffsetshadowOpacityshadowOpacity, 在使用时候, 需要根据具体的需求选择合适的.

1、最简洁的Block动画:包含时间和动画

代码

[UIView animateWithDuration:3 animations:^{ //执行动画 _MyView.transform = CGAffineTransformScale(_MyView.transform, 0.5, 0.5);//缩放 _MyView.transform = CGAffineTransformRotate(_MyView.transform, M_PI_4);//旋转 _MyView.transform = CGAffineTransformTranslate(_MyView.transform, 200, 100);//平移 }];

效果图

图片 4animation1.gif

/** * 位移动画演示 */-positionAnimation{ //使用CABasicAnimation创建基础动画 CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"position"]; anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-75)]; anima.toValue = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-75)]; anima.duration = 1.0f;// 如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。 //anima.fillMode = kCAFillModeForwards; //anima.removedOnCompletion = NO; anima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; [_demoView.layer addAnimation:anima forKey:@"positionAnimation"]; //使用UIView Animation 代码块调用// _demoView.frame = CGRectMake(0, SCREEN_HEIGHT/2-50, 50, 50);// [UIView animateWithDuration:1.0f animations:^{// _demoView.frame = CGRectMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50, 50, 50);// } completion:^(BOOL finished) {// _demoView.frame = CGRectMake(SCREEN_WIDTH/2-25, SCREEN_HEIGHT/2-50, 50, 50);// }];// //使用UIView [begin,commit]模式// _demoView.frame = CGRectMake(0, SCREEN_HEIGHT/2-50, 50, 50);// [UIView beginAnimations:nil context:nil];// [UIView setAnimationDuration:1.0f];// _demoView.frame = CGRectMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50, 50, 50);// [UIView commitAnimations];}

效果图如下:

2、可设置延迟时间和过渡效果的Block动画

代码

[UIView animateWithDuration:3 delay:1 options:UIViewAnimationOptionTransitionCurlDown animations:^{ //执行动画 _MyView.transform = CGAffineTransformScale(_MyView.transform, 0.5, 0.5);//缩放 _MyView.transform = CGAffineTransformRotate(_MyView.transform, M_PI_4);//旋转 _MyView.transform = CGAffineTransformTranslate(_MyView.transform, 200, 100);//平移 } completion:^(BOOL finished) { NSLog(@"动画完成的回调"); }];

UIViewAnimationOptions的枚举值如下,可组合使用

UIViewAnimationOptionLayoutSubviews//进行动画时布局子控件UIViewAnimationOptionAllowUserInteraction//进行动画时允许用户交互UIViewAnimationOptionBeginFromCurrentState//从当前状态开始动画UIViewAnimationOptionRepeat//无限重复执行动画UIViewAnimationOptionAutoreverse//执行动画回路UIViewAnimationOptionOverrideInheritedDuration//忽略嵌套动画的执行时间设置UIViewAnimationOptionOverrideInheritedCurve//忽略嵌套动画的曲线设置UIViewAnimationOptionAllowAnimatedContent//转场:进行动画时重绘视图UIViewAnimationOptionShowHideTransitionViews//转场:移除动画效果UIViewAnimationOptionOverrideInheritedOptions//不继承父动画设置UIViewAnimationOptionCurveEaseInOut//时间曲线,慢进慢出UIViewAnimationOptionCurveEaseIn//时间曲线,慢进UIViewAnimationOptionCurveEaseOut//时间曲线,慢出UIViewAnimationOptionCurveLinear//时间曲线,匀速UIViewAnimationOptionTransitionNone//转场,不使用动画UIViewAnimationOptionTransitionFlipFromLeft//转场,从左向右旋转翻页UIViewAnimationOptionTransitionFlipFromRight//转场,从右向左旋转翻页UIViewAnimationOptionTransitionCurlUp//转场,下往上卷曲翻页UIViewAnimationOptionTransitionCurlDown//转场,从上往下卷曲翻页UIViewAnimationOptionTransitionCrossDissolve//转场,交叉消失和出现UIViewAnimationOptionTransitionFlipFromTop//转场,从上向下旋转翻页UIViewAnimationOptionTransitionFlipFromBottom//转场,从下向上旋转翻页

基础动画-透明度

图片 5基础动画-透明度gif.gif

图片 6旋转.gif

3、Spring动画

usingSpringWithDamping:震动效果,范围0~1,数值越小震动效果越明显initialSpringVelocity:初始速度,数值越大初始速度越快

 [UIView animateWithDuration:3 delay:0 usingSpringWithDamping:0.1 initialSpringVelocity:100 options:UIViewAnimationOptionRepeat animations:^{ //执行动画 _MyView.transform = CGAffineTransformScale(_MyView.transform, 0.5, 0.5);//缩放 _MyView.transform = CGAffineTransformRotate(_MyView.transform, M_PI_4);//旋转 _MyView.transform = CGAffineTransformTranslate(_MyView.transform, 200, 100);//平移 } completion:^(BOOL finished) { }];

效果图

图片 7animation2.gif

/** * 透明度动画 */-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"];}
  • 位移动画
4、Keyframes动画

iOS7.0后新增关键帧动画,支持属性关键帧,不支持路径关键帧options:动画的过渡效果

[UIView animateKeyframesWithDuration:0.5 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubicPaced animations:^{ _MyView.backgroundColor = [UIColor blueColor]; } completion:nil]; [UIView animateKeyframesWithDuration:1 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubicPaced animations:^{ _MyView.backgroundColor = [UIColor grayColor]; } completion:nil]; [UIView animateKeyframesWithDuration:1.5 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubicPaced animations:^{ _MyView.backgroundColor = [UIColor greenColor]; } completion:nil]; [UIView animateKeyframesWithDuration:2 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubicPaced animations:^{ _MyView.backgroundColor = [UIColor redColor]; } completion:nil];

UIViewKeyframeAnimationOptions的枚举值如下,可组合使用:

UIViewAnimationOptionLayoutSubviews//进行动画时布局子控件UIViewAnimationOptionAllowUserInteraction//进行动画时允许用户交互UIViewAnimationOptionBeginFromCurrentState//从当前状态开始动画UIViewAnimationOptionRepeat//无限重复执行动画UIViewAnimationOptionAutoreverse//执行动画回路UIViewAnimationOptionOverrideInheritedDuration//忽略嵌套动画的执行时间设置UIViewAnimationOptionOverrideInheritedOptions//不继承父动画设置UIViewKeyframeAnimationOptionCalculationModeLinear//运算模式:连续UIViewKeyframeAnimationOptionCalculationModeDiscrete//运算模式:离散UIViewKeyframeAnimationOptionCalculationModePaced//运算模式:均匀执行UIViewKeyframeAnimationOptionCalculationModeCubic//运算模式:平滑UIViewKeyframeAnimationOptionCalculationModeCubicPaced//运算模式:平滑均匀

效果图

图片 8animation3.gif

基础动画-缩放

图片 9基础动画-缩放gif.gif

5、转场动画
/** * 缩放动画 */-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"];}
 func positionAnimation() { let animation = CABasicAnimation.init(keyPath: "position") //keyPath为系统提供 animation.fromValue = CGPoint.init(x: margin_ViewMidPosition, y: kScreenH / 2 - margin_Top) animation.toValue = CGPoint.init(x: kScreenW - margin_ViewMidPosition, y: kScreenH / 2 - margin_Top) animation.duration = 1.0 view_Body.layer.add(animation, forKey: "positionAnimation") //key自定义 }
单个视图的过渡效果

代码

[UIView transitionWithView:_MyView duration:1 options:UIViewAnimationOptionOverrideInheritedCurve animations:^{ _MyView.backgroundColor = [UIColor greenColor]; } completion:nil];

效果图

图片 10animation4.gif

基础动画-旋转

图片 11基础动画-旋转gif.gif

  • 旋转动画:
从旧视图转到新视图的动画效果
[UIView transitionFromView:_MyView toView:_view duration:1 options:UIViewAnimationOptionTransitionFlipFromTop completion:nil];
/** * 旋转动画 */-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)];//绕着矢量旋转// anima.duration = 1.0f;// //anima.repeatCount = MAXFLOAT;// [_demoView.layer addAnimation:anima forKey:@"rotateAnimation"];// //CGAffineTransform作用与View// _demoView.transform = CGAffineTransformMakeRotation;// [UIView animateWithDuration:1.0f animations:^{// _demoView.transform = CGAffineTransformMakeRotation;// } completion:^(BOOL finished) {// // }];}

CAAnimation核心动画

在iOS的不同图形层次中都可以写动画代码。越上层,封装程度越高,动画实现越简洁越简单,但是自由度越低;反之亦然。如果想要做出更炫的动画,就必须要了解CAAnimation核心动画了。

基础动画-变色

图片 12基础动画-背景色gif.gif

 func rotateAnimation() { let animation = CABasicAnimation.init(keyPath: "transform.rotation.z") animation.toValue = NSNumber.init(value: Double.pi) animation.duration = 0.1 animation.repeatCount = 1e100 //无限大重复次数 view_Body.layer.add(animation, forKey: "rotateAnimation") }
Core Animation结构

图片 131053533-6eae72f7fd9bd271.png图片 14屏幕快照 2017-04-20 下午9.56.37.png

基础动画(CABasicAnimation),通过设定起始点,终点,时间,动画会沿着你这设定点进行移动。可以看做特殊的CAKeyFrameAnimation

./** * 背景色变化动画 */-backgroundAnimation{ CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"backgroundColor"]; anima.toValue = [UIColor greenColor].CGColor; anima.duration = 1.0f; [_demoView.layer addAnimation:anima forKey:@"backgroundAnimation"];}
  • 缩放动画
开始之前我们需要先了解一个概念:CALayer

CALayer是个与UIView很类似的概念,同样有backgroundColor、frame等相似的属性,我们可以将UIView看做一种特殊的CALayer。但实际上UIView是对CALayer封装,在CALayer的基础上再添加交互功能。UIView的显示必须依赖于CALayer。我们同样可以跟新建view一样新建一个layer,然后添加到某个已有的layer上,同样可以对layer调整大小、位置、透明度等。一般来说,layer可以有两种用途:一是对view相关属性的设置,包括圆角、阴影、边框等参数,更详细的参数请点击这里;二是实现对view的动画操控。因此对一个view进行动画,本质上是对该view的.layer进行动画操纵。

帧动画-关键帧

图片 15帧动画-关键帧.gif

注意点1:KeyPath中key值的设置

实例化方法

 //围绕y轴旋转CABasicAnimation *transformAnima = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];

使用方法animationWithKeyPath:CABasicAnimation进行实例化,并指定Layer的属性作为关键路径进行注册。keyPath决定了基础动画的类型,该值不能随便取,一旦取错就达不到想要的效果。要改变位置就取position,要改变透明度就取opacity,要等比例缩放就取transform.scale...一些常用的animationWithKeyPath值的总结

图片 163D62A8E2-94E2-4FC3-AE05-A71296F4B324.png

/** * 关键帧动画 */-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"]; }-animationDidStart:(CAAnimation *)anim{ NSLog;}-animationDidStop:(CAAnimation *)anim finished:flag{ NSLog;}
 func scaleAnimation() { let animation = CABasicAnimation.init(keyPath: "transform.scale") animation.toValue = NSNumber.init(value: 2.0) animation.duration = 1.0 view_Body.layer.add(animation, forKey: "scaleAnimation") }
注意点2:fillMode属性的理解

该属性定义了你的动画在开始和结束时的动作。默认值是 kCAFillModeRemovedfillMode的作用就是决定当前对象过了非active时间段的行为. 非active时间段是指动画开始之前以及动画结束之后。如果是一个动画CAAnimation,则需要将其removedOnCompletion设置为NO,要不然fillMode不起作用.

kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态kCAFillModeBackwards这个和kCAFillModeForwards是相对的,就是在动画开始前,你只要将动画加入了一个layer,layer便立即进入动画的初始状态。因为有可能出现fromValue不是目前layer的初始状态的情况,如果fromValue就是layer当前的状态,则这个参数就没太大意义。kCAFillModeBoth理解了上面两个,这个就很好理解了,这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态.

帧动画-路径

图片 17帧动画-路径.gif

  • 透明度动画
注意点3

[self.view.layer addAnimation:positionAnima forKey:@"AnimationMoveY"];我们可以根据这个Key找到这个layer

/** * path动画 */-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"];}
注意点4:一些常用的属性

图片 187E7672C6-9B0E-4743-9533-C3B506329F1D.png

帧动画-抖动

图片 19帧动画-抖动.gif

func opacityAnimation() { let animation = CABasicAnimation.init(keyPath: "opacity") animation.fromValue = NSNumber.init(value: 1.0) animation.toValue = NSNumber.init(value: 0.0) animation.duration = 1.0 view_Body.layer.add(animation, forKey: "opacityAnimation") }
我们做一个心跳的效果

代码

//初始化CALayer CALayer *layer = [[CALayer alloc]init]; layer.backgroundColor = [UIColor redColor].CGColor; layer.frame = CGRectMake(100, 100, 100, 100); layer.cornerRadius = 10; [self.view.layer addSublayer:layer]; //配置CABasicAnimation CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; basicAnimation.fromValue = [NSNumber numberWithFloat:1.0]; basicAnimation.toValue = [NSNumber numberWithFloat:1.5]; //当动画执行到toValue指定的状态时是从toValue的状态逆回去,还是直接跳到fromValue的状态再执行一遍 basicAnimation.autoreverses = YES; basicAnimation.removedOnCompletion = NO; basicAnimation.duration = 0.5; basicAnimation.repeatCount = MAXFLOAT; //把动画内容添加到layer上 [layer addAnimation:basicAnimation forKey:@"basicAnimation"];

图片 20basicAnimation.gif

CABasicAnimation只能从一个数值(fromValue)变到另一个数值,而CAKeyframeAnimation会使用一个NSArray保存这些数值

属性介绍

  • values:就是上述的NSArray对象。里面的元素称为”关键帧”。动画对象会在指定的时间内,依次显示values数组中的每一个关键帧

  • path:可以设置一个CGPathRefCGMutablePathRef,让层跟着路径移动。path只对CALayer的anchorPoint和position起作用。如果你设置了path,那么values将被忽略

  • keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧.当keyTimes没有设置的时候,各个关键帧的时间是平分的

value方式代码

 //创建动画对象 CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; //设置value NSValue *value1=[NSValue valueWithCGPoint:CGPointMake]; NSValue *value2=[NSValue valueWithCGPoint:CGPointMake]; NSValue *value3=[NSValue valueWithCGPoint:CGPointMake]; NSValue *value4=[NSValue valueWithCGPoint:CGPointMake]; NSValue *value5=[NSValue valueWithCGPoint:CGPointMake]; NSValue *value6=[NSValue valueWithCGPoint:CGPointMake]; animation.values=@[value1,value2,value3,value4,value5,value6]; //重复次数 默认为1 animation.repeatCount=MAXFLOAT; //设置是否原路返回默认为不 animation.autoreverses = YES; //设置移动速度,越小越快 animation.duration = 4.0f; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeForwards; //给这个view加上动画效果 [_keyFrameView.layer addAnimation:animation forKey:nil]; 

图片 21KeyFrameValue.gif

path方法代码

CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"]; UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake]; [path addLineToPoint:CGPointMake]; [path addLineToPoint:CGPointMake]; [path addLineToPoint:CGPointMake]; anima.path = path.CGPath; anima.duration = 2.0f; anima.repeatCount= MAXFLOAT; anima.autoreverses = NO; anima.removedOnCompletion = NO; anima.fillMode = kCAFillModeForwards; [_keyFrameView.layer addAnimation:anima forKey:@"pathAnimation"];

图片 22KeyFramePath.gif

动画组(CAAnimationGroup)是核心动画中又一个比较重要的知识点。动画组顾名思义就是一组动画,它可以将多个动画对象保存起来,然后再将其添加到layer上,让组中所有的动画对象同时并发执行。

 /****************** 创建平移动画 ******************/ CABasicAnimation *basicAnim = [CABasicAnimation animation]; // 设置动画属性 basicAnim.keyPath = @"position.y"; basicAnim.toValue = @350; /****************** 创建缩放动画 ******************/ CABasicAnimation *scaleAnim = [CABasicAnimation animation]; // 设置动画属性 scaleAnim.keyPath = @"transform.scale"; scaleAnim.toValue = @0.5; ; /****************** 创建动画组 ******************/ CAAnimationGroup *groupAnim = [CAAnimationGroup animation]; // 将动画对象都添加到CAAnimationGroup对象中 groupAnim.animations = @[basicAnim, scaleAnim]; /****************** 通过动画组对象统一设置动画属性和状态 ******************/ // 设置动画的执行时长 groupAnim.duration = 0.5; // 动画完成时保持在最新的状态 groupAnim.removedOnCompletion = NO; groupAnim.fillMode = kCAFillModeForwards; groupAnim.duration = 2.0f; groupAnim.repeatCount= MAXFLOAT; groupAnim.autoreverses = YES; groupAnim.removedOnCompletion = NO; groupAnim.fillMode = kCAFillModeForwards; /****************** 将动画组对象添加到redView的layer上 ******************/ [_animationGroupView.layer addAnimation:groupAnim forKey:nil];

图片 23animationGroup.gif

CATransition是CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果动画属性:type:动画过渡类型subtype:动画过渡方向startProgress:动画起点(在整体动画的百分比)endProgress:动画终点(在整体动画的百分比)

/** * 抖动效果 */-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"];}
  • 背景色动画
转场动画过渡效果

图片 24屏幕快照 2016-05-25 20.41.32.png

注意:抖动最好加一个timer时间判断 不然她会抖到你手机没电!

帧动画-弹来弹去

图片 25帧动画-弹来弹去.gif

 func backgroundColorAnimation() { let animation = CABasicAnimation.init(keyPath: "backgroundColor") animation.toValue = UIColor.green.cgColor //因为layer层动画, 所以需要使用cgColor animation.duration = 1.0 view_Body.layer.add(animation, forKey: "backgroundColorAnimation") }
//弹来弹去-calculationAnimation{ //需要实现的帧动画 CAKeyframeAnimation *animation = [CAKeyframeAnimation animation]; animation.keyPath = @"transform.scale"; animation.values = @[@1.0,@1.3,@0.9,@1.15,@0.95,@1.02,@1.0]; animation.duration = 1; animation.calculationMode = kCAAnimationCubic; //把动画添加上去 [_demoView.layer addAnimation:animation forKey:nil];}

CAKeyframeAnimationCABasicAnimation 都属于CAPropertyAnimatin 的子类。不同的是 CABasicAnimation 只能从一个数值(fromValue)变换成另一个数值(toValue),而 CAKeyframeAnimation 则会使用一个数组(values) 保存一组关键帧, 也可以给定一个路径(path)制作动画。

这个动画 是一个我个人很喜欢的动画 可能这么看 你感觉不出 他有什么用? 这里附加一个实例的动画 我想你们会收到启发的

图片 26帧动画-弹来弹去实例.gif

组合动画-同时进行

图片 27组合动画-同时进行.gif

CAKeyframeAnimation主要有 三个 重要属性:

-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.8f]; anima2.toValue = [NSNumber numberWithFloat:2.0f]; //旋转动画 CABasicAnimation *anima3 = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; anima3.toValue = [NSNumber numberWithFloat:M_PI*4]; //组动画 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"];}
  • values:存放关键帧(keyframe)的数组,动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧 .
  • path:可以设置一个 CGPathRefCGMutablePathRef,让层跟着路径移动. path 只对 CALayeranchorPointposition 起作用, 如果设置了path,那么values将被忽略.
  • keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0, keyTimes 中的每一个时间值都对应 values 中的每一帧.当 keyTimes 没有设置的时候,各个关键帧的时间是根据 duration 平分的。

组合动画-连续进行

图片 28组合动画-连续进行.gif

以抖动截图为例, 效果图如下:

/** * 顺序执行的组动画 */-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"];}

图片 29抖动.gif

以上就是一些简单而且实用的 基础动画

动画代码如下:

虽然看上去gif 都挺丑的

  • 关键帧动画

但是我相信 如果你能把这些效果用好

不管你的app 实际内容有多少 精不精彩 至少只是一个效果 界面

func keyFrameAnimation() { let animation = CAKeyframeAnimation.init(keyPath: "position") let value_0 = CGPoint.init(x: margin_ViewMidPosition, y: kScreenH / 2 - margin_ViewWidthHeight) let value_1 = CGPoint.init(x: kScreenW / 3, y: kScreenH / 2 - margin_ViewWidthHeight) let value_2 = CGPoint.init(x: kScreenW / 3, y: kScreenH / 2   margin_ViewMidPosition) let value_3 = CGPoint.init(x: kScreenW * 2 / 3, y: kScreenH / 2   margin_ViewMidPosition) let value_4 = CGPoint.init(x: kScreenW * 2 / 3, y: kScreenH / 2 - margin_ViewWidthHeight) let value_5 = CGPoint.init(x: kScreenW - margin_ViewMidPosition, y: kScreenH / 2 - margin_ViewWidthHeight) animation.values = [value_0, value_1, value_2, value_3, value_4, value_5] animation.duration = 2.0 view_Body.layer.add(animation, forKey: "keyFrameAnimation") }

就足以让你的app 发光发彩!!!

  • 路径动画

最后老规矩。

老猫在这里祝大家:永无BUG。不再加班!

func pathAnimation() { let animation = CAKeyframeAnimation.init(keyPath: "position") let path = UIBezierPath.init(arcCenter: CGPoint.init(x: kScreenW / 2, y: kScreenH / 2), radius: 60, startAngle: 0.0, endAngle: .pi * 2, clockwise: true) animation.duration = 2.0 animation.path = path.cgPath view_Body.layer.add(animation, forKey: "pathAnimation") }
  • 抖动动画
func shakeAnimation() { let animation = CAKeyframeAnimation.init(keyPath: "transform.rotation") let value_0 = NSNumber.init(value: -Double.pi / 180 * 8) let value_1 = NSNumber.init(value: Double.pi / 180 * 8) animation.values = [value_0, value_1, value_0] animation.duration = 1.0 animation.repeatCount = 1e100 view_Body.layer.add(animation, forKey: "shakeAnimation") }

CAAnimationGroupCAAnimation 的子类,可以保存一组动画对象,可以保存基础动画、关键帧动画等,数组中所有动画对象可以同时并发运行, 也可以通过实践设置为串行连续动画.

效果截图如下:

图片 30组动画2.gif

动画代码如下:

  • 同时
 //同时 func sameTimeAnimation() { let animation_Position = CAKeyframeAnimation.init(keyPath: "position") let value_0 = CGPoint.init(x: margin_ViewMidPosition, y: kScreenH / 2 - margin_ViewMidPosition) let value_1 = CGPoint.init(x: kScreenW / 3, y: kScreenH / 2 - margin_ViewMidPosition) let value_2 = CGPoint.init(x: kScreenW / 3, y: kScreenH / 2   margin_ViewMidPosition) let value_3 = CGPoint.init(x: kScreenW / 3 * 2, y: kScreenH / 2   margin_ViewMidPosition) let value_4 = CGPoint.init(x: kScreenW / 3 * 2, y: kScreenH / 2 - margin_ViewMidPosition) let value_5 = CGPoint.init(x: kScreenW - margin_ViewMidPosition, y: kScreenH / 2 - margin_ViewMidPosition) animation_Position.values = [value_0, value_1, value_2, value_3, value_4, value_5] let animation_BGColor = CABasicAnimation.init(keyPath: "backgroundColor") animation_BGColor.toValue = UIColor.green.cgColor let animation_Rotate = CABasicAnimation.init(keyPath: "transform.rotation") animation_Rotate.toValue = NSNumber.init(value: Double.pi * 4) let animation_Group = CAAnimationGroup() animation_Group.animations = [animation_Position, animation_BGColor, animation_Rotate] animation_Group.duration = 4.0 view_Body.layer.add(animation_Group, forKey: "groupAnimation") }
  • 连续
 //连续动画 最主要的是处理好各个动画时间的衔接 func goOnAnimation() { //定义一个动画开始的时间 let currentTime = CACurrentMediaTime() let animation_Position = CABasicAnimation.init(keyPath: "position") animation_Position.fromValue = CGPoint.init(x: margin_ViewMidPosition, y: kScreenH / 2) animation_Position.toValue = CGPoint.init(x: kScreenW / 2, y: kScreenH / 2) animation_Position.duration = 1.0 animation_Position.fillMode = "forwards" //只在前台 animation_Position.isRemovedOnCompletion = false //切出界面再回来动画不会停止 animation_Position.beginTime = currentTime view_Body.layer.add(animation_Position, forKey: "positionAnimation") let animation_Scale = CABasicAnimation.init(keyPath: "transform.scale") animation_Scale.fromValue = NSNumber.init(value: 0.7) animation_Scale.toValue = NSNumber.init(value: 2.0) animation_Scale.duration = 1.0 animation_Scale.fillMode = "forwards" animation_Scale.isRemovedOnCompletion = false animation_Scale.beginTime = currentTime   1.0 view_Body.layer.add(animation_Scale, forKey: "scaleAnimation") let animation_Rotate = CABasicAnimation.init(keyPath: "transform.rotation") animation_Rotate.toValue = NSNumber.init(value: Double.pi * 4) animation_Rotate.duration = 1.0 animation_Rotate.fillMode = "forwards" animation_Rotate.isRemovedOnCompletion = false animation_Rotate.beginTime = currentTime   2.0 view_Body.layer.add(animation_Rotate, forKey: "rotateAnimation") }

CATransitionCAAnimation 的子类,用于做过渡动画或者 转场 动画,能够为层提供移出屏幕和移入屏幕的动画效果。

过渡动画通过 type 设置不同的动画效果, CATransition 有多种过渡效果, 但其实 Apple 官方的SDK只提供了种:

  • fade 淡出 默认
  • moveIn 覆盖原图
  • push 推出
  • reveal 底部显示出来

私有API提供了其他很多非常炫的过渡动画,如 cubesuckEffectoglFliprippleEffectpageCurl(卷曲翻页 向上翻页)、pageUnCurl(卷曲翻页 向下翻页)、cameraIrisHollowOpencameraIrisHollowClose等。

: 因 Apple 不提供维护,并且有可能造成你的app审核不通过, 所以不建议开发者们使用这些私有API.

效果如下:

图片 31过渡动画.gif

翻页动画代码如下:

 func curlAnimation() { let animation_Curl = CATransition() animation_Curl.type = "pageCurl" animation_Curl.subtype = "fromRight" animation_Curl.duration = 1.0 view_Body.layer.add(animation_Curl, forKey: "curlAnimation") }
  1. 进度条效果如下:图片 32进度条.gif这里主要用到了 CAShapeLayer CAGradientLayer, 使用 CAGradientLayer 画进度圈(GPU执行, 高效), 然后使用 CAGradientLayer 渐变色layer, 结合动画显示进度条.代码如下:
  • UI视图
func createView() { label_Progress = UILabel() label_Progress.text = "" label_Progress.textAlignment = .center label_Progress.font = UIFont.systemFont(ofSize: 25) addSubview(label_Progress) label_Progress.snp.makeConstraints {  in make.centerX.centerY.equalTo make.width.equalTo make.height.equalTo } layer_BackPath = CAShapeLayer() layer_BackPath.fillColor = UIColor.clear.cgColor //填充颜色 layer_BackPath.strokeColor = UIColor.white.withAlphaComponent.cgColor //划线颜色 layer_BackPath.lineWidth = width_MainPath layer.addSublayer(layer_BackPath) layer_MainPathLayer = CAShapeLayer() layer_MainPathLayer.fillColor = UIColor.clear.cgColor layer_MainPathLayer.strokeColor = UIColor.white.cgColor layer_MainPathLayer.lineWidth = width_MainPath layer.addSublayer(layer_MainPathLayer) //渐变色 layer_Gradient = CAGradientLayer() layer_Gradient.frame = CGRect.init(x: 0, y: 0, width: kScreenW, height: kScreenH) layer_Gradient.type = "axial" //线性变化 默认目前只有这一个type layer_Gradient.colors = [UIColor.init(hex: 0xf31414).cgColor, UIColor.init(hex: 0xf27200).cgColor, UIColor.init(hex: 0xffff00).cgColor, UIColor.init(hex: 0x2bee22).cgColor, UIColor.init(hex: 0x32a7eb).cgColor] layer_Gradient.locations = [0, 0.3, 0.5, 0.7, 1] //每个渐变颜色的终止位置,这些值必须是递增的,数组的长度和colors的长度最好一致 //startPoint endPoint 分别表示渐变层的起始位置和终止位置,这两个点被定义在一个单元坐标空间,[0,0]表示左上角位置,[1,1]表示右下角位置,默认值分别是[.5,0] and [.5,1]; layer_Gradient.startPoint = CGPoint.init(x: 0, y: 0) layer_Gradient.endPoint = CGPoint.init(x: 1, y: 0) layer.addSublayer(layer_Gradient) }
  • 进度
func drawCircle(){ //贝塞尔曲线画圆 let path_Back = UIBezierPath.init(arcCenter: CGPoint.init(x: kScreenW / 2, y: kScreenH / 2), radius: kScreenW / 5 - width_MainPath, startAngle: CGFloat.pi, endAngle: CGFloat.pi * 3, clockwise: true) let path_Main = UIBezierPath.init(arcCenter: CGPoint.init(x: kScreenW / 2, y: kScreenH / 2), radius: kScreenW / 5 - width_MainPath   3, startAngle: CGFloat.pi, endAngle: CGFloat.pi * 3, clockwise: true) layer_BackPath.path = path_Back.cgPath layer_MainPathLayer.path = path_Main.cgPath layer_Gradient.mask = layer_MainPathLayer //用 layer_MainPathLayer 截取渐变层 //动画 显示路径 let animation = CABasicAnimation.init(keyPath: "strokeEnd") animation.duration = CFTimeInterval(Double * 0.01) animation.fromValue = NSNumber.init animation.toValue = NSNumber.init(value: Double * 0.01) animation.fillMode = "forwards" animation.isRemovedOnCompletion = false //完成后不删除动画 layer_MainPathLayer.add(animation, forKey: "strokeEndAnimation") if progress > 0{ DispatchQueue.global().async { self.timer_ProgressLabel = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(YTProgressView.progressLabelTimerAction), userInfo: nil, repeats: true) RunLoop.current.run() } }else{ label_Progress.text = "0%" } } func progressLabelTimerAction() { DispatchQueue.main.async { self.label_Progress.text = String(self.num_Progress)   "%" } if num_Progress >= progress{ //销毁计时器 timer_ProgressLabel.invalidate() timer_ProgressLabel = nil }else{ num_Progress  = 1 } }

这里只展示了核心代码, 详细代码可到github下载完整代码:

  1. 弹球, 仿Path菜单效果
  • 点击红色按钮,红色按钮旋转。(旋转动画
  • 黑色小按钮依次弹出,并且带有旋转效果。(位移动画、旋转动画、组动画
  • 点击黑色小按钮,其他按钮消失,被点击的黑色按钮变大变淡消失。(缩放动画、alpha动画、组动画图片 33tanqiu.gif
  1. 仿钉钉菜单效果

    图片 34dingding.png

    动画实现用到了位移动画和缩放动画, 其实不难.

  2. 点赞

    图片 35点赞.gif

看完整篇文章相信你对 iOS 中的动画有了一个详细的了解, 其实单个动画都是比较简单的, 而复杂的动画其实都是由一个个简单的动画组装而成的,所以遇到比较难得动画需求, 我们只要充分组装不同的动画,就能实现出满意的效果.

好记性不如烂笔头, 光说不练假把戏, 建议大家结合我的代码, 自己边看边练习, 这样才能记得牢, 才能转换成自己的知识.

github:

如果觉得对你还有些用,给个喜欢关注吧。你的支持是我继续的动力。

版权声明:本文由韦德娱乐1946_韦德娱乐1946网页版|韦德国际1946官网发布于网络编程,转载请注明出处:常用动画,iOS动画集锦