转载

iOS开发之动画CoreAnimation 总结

属性动画

通过改变图层 或者视图上面的属性值 产生动画

相关知识点

iOS 动画主要是指Core Animation框架。官方使用文档地址为: Core Animation Guide 。

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

Core Animation类图以及常用字段

Core Animation类的继承关系图

iOS开发之动画CoreAnimation 总结

属性动画常用的方法属性

  • 1、初始化 : + (instancetype)animationWithKeyPath:(nullable NSString *)path
    • path:需要产生动画效果的属性,如中心点—>移动
  • 2、keyPath 描述 动画的属性
  • 3、改变动画的属性:
    • transform.scale = 比例转换
    • transform.scale.x =
    • transform.scale.y
    • transform.rotation.z
    • opacity = 透明度
    • zPosition
    • backgroundColor = 背景颜色
    • cornerRadius = 拐角
    • borderWidth
    • bounds
    • contents = 内容
    • contentsRect
    • frame
    • hidden
    • masksToBounds
    • opacity
    • position
    • shadowColor = 阴影颜色
    • shadowOffset = 阴影偏移量
    • shadowOpacity = 阴影透明度
    • shadowRadius = 阴影拐角

基础动画(CABasicAnimation)

通过改变某个属性的值 到某个值(只能设置两个值来产生动画)

  • fromValue :开始值(如果不设置 不会返回到初始位置)
  • toValue :结束值
  • byValue :通过哪个值

CAAnimation 是所有动画的子类

常用属性

  • duration 动画的持续时间 默认为0 持续时间 受速度的影响 实际的动画完成时间 = 持续时间/速度

  • beginTime :动画开始的时间 默认为0

  • duration 动画的持续时间 默认为0 持续时间 受速度的影响 实际的动画完成时间 = 持续时间/速度

  • repeatCount : 动画的重复次数,默认是0(只播放一次)

  • timeOffset 动画播放时间的偏移量

  • repeatDuration 动画循环的持续时间 只能设置其中的一个属性 repeatCount/repeatDuration

  • autoreverses : 是否以动画的形式 返回之前的状态

  • .fillMode 设置当前对象在非活动时间段的状态

    • 要想fillMode有效 需设置removedOnCompletion = NO
    • kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态
    • kCAFillModeBackwards 立即进入动画的初始状态并等待动画开始
    • kCAFillModeBoth 动画加入后开始之前 layer处于动画初始状态 动画结束后layer保持动画最后的状态
    • kCAFillModeRemoved 默认值 动画结束后 layer会恢复到之前的状态

CAAnimation 动画属性 方法介绍

  • 初始化 animation
  • 按时
  • delegate : 动画代理。能够检测动画的执行和结束。 (CAAnimationDelegate)
    • -(void)animationDidStart:(CAAnimation *)anim;
    • -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
  • timingFunction : (functionWithName)控制动画的显示节奏系统提供五种值选择,分别是:
    • kCAMediaTimingFunctionLinear 线性动画
    • kCAMediaTimingFunctionEaseIn 先慢后快(慢进快出)
    • kCAMediaTimingFunctionEaseOut 先快后慢(快进慢出)
    • kCAMediaTimingFunctionEaseInEaseOut 先慢后快再慢
    • kCAMediaTimingFunctionDefault 默认,也属于中间比较快
  • type : 过渡动画的动画类型,系统提供了四种过渡动画。
    • kCATransitionFade 渐变效果
    • kCATransitionMoveIn 进入覆盖效果
    • kCATransitionPush 推出效果
    • kCATransitionReveal 揭露离开效果
  • subtype : 过渡动画的动画方向

    • kCATransitionFromRight 从右侧进入
    • kCATransitionFromLeft 从左侧进入
    • kCATransitionFromTop 从顶部进入
    • kCATransitionFromBottom 从底部进入

代码示例

#import "ViewController.h" @interface ViewController () @property(nonatomic,strong) CALayer *layer; @property(nonatomic,strong) CALayer *petalLayer; @end @implementation ViewController - (void)viewDidLoad {     [super viewDidLoad];     self.view.layer.backgroundColor =                 [UIColor colorWithRed:0.913 green:0.614 blue:0.688 alpha:1.000].CGColor;     [self.view.layer addSublayer:self.layer];     [self.view.layer addSublayer:self.petalLayer]; }  //移动中心点(掉落) -(void)demo1:(CGPoint)toValue{ //利用KVO检测position属性     CABasicAnimation *animation =             [CABasicAnimation animationWithKeyPath:@"position"];     /*     CGPoint —>转id      CGPoint —> NSValue      */     animation.fromValue = [NSValue valueWithCGPoint:self.petalLayer.position];     animation.toValue =[NSValue valueWithCGPoint:toValue];     animation.duration = 3;//设置动画的执行时间     animation.speed = 2;//动画速度,动画执行的总时间受动画速度的影响     //设置动画的timingFunction显示节奏     animation.timingFunction =             [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];          //设置动画在完成的时候固定在完成的状态,这个属性必须把removed设置为NO     animation.removedOnCompletion = NO;     animation.fillMode = kCAFillModeBoth;          //layer -> addAnimation :添加动画     [self.petalLayer addAnimation:animation forKey:@"可以通过key来找到这个动画"];     /*     查找某个key 对应的动画      CABasicAnimation *ad =             (CABasicAnimation *)[self.petalLayer              animationForKey:@"可以通过key来找到这个动画"];      */ }  //心跳效果 -(void)demo2{     UIImage *image =[UIImage imageNamed:@"心跳.png"];     self.layer.contents = (id)image.CGImage;     self.layer.bounds =CGRectMake(0, 0, image.size.width/10, image.size.height/10);     self.layer.position = self.view.center;          CABasicAnimation *animation =[CABasicAnimation animationWithKeyPath:@"bounds"];     /*      1、放大后 以动画的效果 还原到原来的位置      2、先慢后快      3、一直循环      */     animation.fromValue = [NSValue valueWithCGRect:self.layer.bounds];     animation.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, image.size.width/3, image.size.height/3)];     animation.repeatCount =HUGE;     //设置动画的持续时间     animation.duration =0.5;     //设置以动画的效果还原到原来的位置     animation.autoreverses =YES;     animation.timingFunction =[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];     [self.layer addAnimation:animation forKey:nil];      } -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{     [self demo1:[[touches anyObject] locationInView:self.view]];         [self demo2];  }  -(CALayer *)layer{     if (_layer) {         return _layer;     }     _layer =[CALayer layer];     _layer.position = CGPointMake(self.view.center.x, self.view.center.y+100);     UIImage *image= [UIImage imageNamed:@"H4"];     _layer.bounds = CGRectMake(0, 0, image.size.width/3, image.size.height/3);     _layer.contents = (id)image.CGImage;//设置layer上的内容     return _layer;      } -(CALayer *)petalLayer{     if (_petalLayer) {         return _petalLayer;     }     _petalLayer = [CALayer layer];     _petalLayer.position = CGPointMake(self.view.center.x, 50);     UIImage *image= [UIImage imageNamed:@"H3"];     _petalLayer.bounds = CGRectMake(0, 0, image.size.width, image.size.height);     _petalLayer.contents = (id)image.CGImage;//设置layer上的内容     return _petalLayer; } 

iOS动画的调用方式

第一种:UIView 代码块调用

    _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]; 

第三种:使用Core Animation中的类

    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;     [_demoView.layer addAnimation:anima forKey:@"positionAnimation"]; 

iOS动画的使用

1.基础动画(CABaseAnimation)

重要属性

fromValue: keyPath对应的初始值

toValue: keyPath对应的结束值

基础动画主要提供了对于CALayer对象中的可变属性进行简单动画的操作。比如:位移、透明度、缩放、旋转、背景色等等。

效果演示:

iOS开发之动画CoreAnimation 总结

位移动画代码演示:

    //使用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;     //anima.fillMode = kCAFillModeForwards;     //anima.removedOnCompletion = NO;     [_demoView.layer addAnimation:anima forKey:@"positionAnimation"]; 

注意点

如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。

2.关键帧动画(CAKeyframeAnimation)

CAKeyframeAnimation和CABaseAnimation都属于CAPropertyAnimatin的子类。CABaseAnimation只能从一个数值(fromValue)变换成另一个数值(toValue),而CAKeyframeAnimation则会使用一个NSArray保存一组关键帧。

重要属性

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

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

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

效果演示:

iOS开发之动画CoreAnimation 总结

圆形路径动画代码演示:

    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"]; 

说明:CABasicAnimation可看做是最多只有2个关键帧的CAKeyframeAnimation

3.组动画(CAAnimationGroup)

CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行。

重要属性

animations: 用来保存一组动画对象的NSArray

效果演示:

iOS开发之动画CoreAnimation 总结

组动画代码演示:

    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"]; 

4.过渡动画(CATransition)

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

重要属性

type:动画过渡类型

Apple 官方的SDK其实只提供了四种过渡效果。

  • kCATransitionFade 渐变效果
  • kCATransitionMoveIn 进入覆盖效果
  • kCATransitionPush 推出效果
  • kCATransitionReveal 揭露离开效果
    私有API提供了其他很多非常炫的过渡动画,比如@"cube"、@"suckEffect"、@"oglFlip"、 @"rippleEffect"、@"pageCurl"、@"pageUnCurl"、@"cameraIrisHollowOpen"、@"cameraIrisHollowClose"等。
    注意点
    私有api,不建议开发者们使用。因为苹果公司不提供维护,并且有可能造成你的app审核不通过。

subtype:动画过渡方向

  • kCATransitionFromRight 从右侧进入
  • kCATransitionFromLeft 从左侧进入
  • kCATransitionFromTop 从顶部进入
  • kCATransitionFromBottom 从底部进入

startProgress:动画起点(在整体动画的百分比)

endProgress:动画终点(在整体动画的百分比)

效果演示:

iOS开发之动画CoreAnimation 总结

###5.综合案例

5.1 仿Path菜单效果

效果演示:

iOS开发之动画CoreAnimation 总结

动画解析:

1、点击红色按钮,红色按钮旋转。(旋转动画)

2、黑色小按钮依次弹出,并且带有旋转效果。(位移动画、旋转动画、组动画)

3、点击黑色小按钮,其他按钮消失,被点击的黑色按钮变大变淡消失。(缩放动画、alpha动画、组动画)

博主的话:代码过多,这里不做演示。文章最后提供代码下载地址。

5.2 仿钉钉菜单效果

效果演示:

iOS开发之动画CoreAnimation 总结

看上去挺炫的,其实实现很简单,就是位移动画+缩放动画。

5.3 点赞烟花效果动画

效果演示:

iOS开发之动画CoreAnimation 总结

这里其实只有按钮变大效果使用的缩放动画。烟花效果 使用的是一种比较特殊的动画--粒子动画。

一个粒子系统一般有两部分组成:

1、CAEmitterCell:可以看作是单个粒子的原型(例如,一个单一的粉扑在一团烟雾)。当散发出一个粒子,UIKit根据这个发射粒子和定义的基础上创建一个随机粒子。此原型包括一些属性来控制粒子的图片,颜色,方向,运动,缩放比例和生命周期。

2、CAEmitterLayer:主要控制发射源的位置、尺寸、发射模式、发射源的形状等等。

以上两个类的属性还是比较多的,这里就不细讲了。大家可以google一下,详细的了解吧。

##总结任何复杂的动画其实都是由一个个简单的动画组装而成的,只要我们善于分解和组装,我们就能实现出满意的效果。动画其实也不是那么难。

感谢:

原文  http://blog.treney.com/index.php/archives/CoreAnimation2.html
正文到此结束
Loading...