iOS中的动画

iOS中的动画主要分为两种:UIView动画,核心动画。

一、UIView动画

UIKit直接将动画集成到UIView类中,当内部的一些属性发生改变时,UIView将为这些改变提供动画支持。
UIView动画能够设置的动画属性有:

  • frame
  • bounds
  • center
  • transform
  • alpha
  • backgroundColor
  • contentStretch

普通方式实现

相关方法及实例如下:

// 第一个参数: 动画标识
// 第二个参数: 附加参数,在设置代理情况下,此参数将发送到setAnimationWillStartSelector和setAnimationDidStopSelector所指定的方法,大部分情况,设置为nil.
[UIView beginAnimations:@"translation" context:nil];
//设置动画代理
[UIView setAnimationDelegate:self];
//设置动画开始时执行方法
[UIView setAnimationWillStartSelector:@selector(animationStart)];
//设置动画停止时执行方法
[UIView setAnimationDidStopSelector:@selector(animationStop)];
//设置动画持续时间
[UIView setAnimationDuration:1.0];
//设置动画延迟执行时间
[UIView setAnimationDelay:2.0];
//设置动画持续次数
[UIView setAnimationRepeatCount:5.0];
//设置动画的曲线
/*
UIViewAnimationCurve的枚举值:
UIViewAnimationCurveEaseInOut,         // 慢进慢出(默认值)
UIViewAnimationCurveEaseIn,            // 慢进
UIViewAnimationCurveEaseOut,           // 慢出
UIViewAnimationCurveLinear             // 匀速
*/
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
//设置是否从当前状态开始播放动画
/*假设上一个动画正在播放,且尚未播放完毕,我们将要进行一个新的动画:
当为YES时:动画将从上一个动画所在的状态开始播放
当为NO时:动画将从上一个动画所指定的最终状态开始播放(此时上一个动画马上结束)*/
[UIView setAnimationBeginsFromCurrentState:YES];
//设置动画是否继续执行相反的动画
[UIView setAnimationRepeatAutoreverses:NO];
//是否禁用动画效果(对象属性依然会被改变,只是没有动画效果)
[UIView setAnimationsEnabled:NO];
//设置视图的过渡效果
/* 第一个参数:UIViewAnimationTransition的枚举值如下
UIViewAnimationTransitionNone,              //不使用动画
UIViewAnimationTransitionFlipFromLeft,      //从左向右旋转翻页
UIViewAnimationTransitionFlipFromRight,     //从右向左旋转翻页
UIViewAnimationTransitionCurlUp,            //从下往上卷曲翻页
UIViewAnimationTransitionCurlDown,          //从上往下卷曲翻页
第二个参数:需要过渡效果的View
第三个参数:是否使用视图缓存,YES:视图在开始和结束时渲染一次;NO:视图在每一帧都渲染*/
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.redIV cache:YES];
//提交动画
[UIView commitAnimations];

简单的Block动画

ios4.0以后增加了Block动画块,提供了更简洁的方式来实现动画.日常开发中一般也是使用Block形式创建动画。
常用方法如下:

//最简洁的Block动画:包含时间和动画
[UIView animateWithDuration:(NSTimeInterval)  //动画持续时间
              animations:^{
              //执行的动画
 }];
//带有动画提交回调的Block动画
[UIView animateWithDuration:(NSTimeInterval)  //动画持续时间
              animations:^{
            //执行的动画
 }                completion:^(BOOL finished) {
            //动画执行提交后的操作
 }];
//可以设置延时时间和过渡效果的Block动画
[UIView animateWithDuration:(NSTimeInterval) //动画持续时间
                   delay:(NSTimeInterval) //动画延迟执行的时间
                 options:(UIViewAnimationOptions) //动画的过渡效果
              animations:^{
               //执行的动画
 }                completion:^(BOOL finished) {
               //动画执行提交后的操作
 }];

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

1.常规动画属性设置(可以同时选择多个进行设置)
UIViewAnimationOptionLayoutSubviews:动画过程中保证子视图跟随运动。**提交动画的时候布局子控件,表示子控件将和父控件一同动画。**
UIViewAnimationOptionAllowUserInteraction:动画过程中允许用户交互。
UIViewAnimationOptionBeginFromCurrentState:所有视图从当前状态开始运行。
UIViewAnimationOptionRepeat:重复运行动画。
UIViewAnimationOptionAutoreverse :动画运行到结束点后仍然以动画方式回到初始点。**执行动画回路,前提是设置动画无限重复**
UIViewAnimationOptionOverrideInheritedDuration:忽略嵌套动画时间设置。**忽略外层动画嵌套的时间变化曲线**
UIViewAnimationOptionOverrideInheritedCurve:忽略嵌套动画速度设置。**通过改变属性和重绘实现动画效果,如果key没有提交动画将使用快照**
UIViewAnimationOptionAllowAnimatedContent:动画过程中重绘视图(注意仅仅适用于转场动画)。
UIViewAnimationOptionShowHideTransitionViews:视图切换时直接隐藏旧视图、显示新视图,而不是将旧视图从父视图移除(仅仅适用于转场动画)**用显隐的方式替代添加移除图层的动画效果**
UIViewAnimationOptionOverrideInheritedOptions :不继承父动画设置或动画类型。**忽略嵌套继承的�选项**
2.动画速度控制(可从其中选择一个设置)时间函数曲线相关**时间曲线函数**
UIViewAnimationOptionCurveEaseInOut:动画先缓慢,然后逐渐加速。
UIViewAnimationOptionCurveEaseIn :动画逐渐变慢。
UIViewAnimationOptionCurveEaseOut:动画逐渐加速。
UIViewAnimationOptionCurveLinear :动画匀速执行,默认值。
3.转场类型(仅适用于转场动画设置,可以从中选择一个进行设置,基本动画、关键帧动画不需要设置)**转场动画相关的**
UIViewAnimationOptionTransitionNone:没有转场动画效果。
UIViewAnimationOptionTransitionFlipFromLeft :从左侧翻转效果。
UIViewAnimationOptionTransitionFlipFromRight:从右侧翻转效果。
UIViewAnimationOptionTransitionCurlUp:向后翻页的动画过渡效果。
UIViewAnimationOptionTransitionCurlDown :向前翻页的动画过渡效果。
UIViewAnimationOptionTransitionCrossDissolve:旧视图溶解消失显示下一个新视图的效果。
UIViewAnimationOptionTransitionFlipFromTop :从上方翻转效果。    
UIViewAnimationOptionTransitionFlipFromBottom:从底部翻转效果。

补充:关于最后一组转场动画它一般是用在这个方法中的:
[UIView transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^ __nullable)(BOOL finished))completion]
该方法效果是插入一面视图移除一面视图,期间可以使用一些转场动画效果。

Spring动画

iOS7.0以后新增了Spring动画(IOS系统动画大部分采用Spring Animation, 适用所有可被添加动画效果的属性)

[UIView animateWithDuration:(NSTimeInterval)//动画持续时间
                   delay:(NSTimeInterval)//动画延迟执行的时间
  usingSpringWithDamping:(CGFloat)//震动效果,范围0~1,数值越小震动效果越明显
   initialSpringVelocity:(CGFloat)//初始速度,数值越大初始速度越快
                 options:(UIViewAnimationOptions)//动画的过渡效果
              animations:^{
                 //执行的动画
 }
                  completion:^(BOOL finished) {
                 //动画执行提交后的操作
 }];

Keyframes动画

iOS7.0后新增了关键帧动画,支持属性关键帧,不支持路径关键帧

[UIView animateKeyframesWithDuration:(NSTimeInterval)//动画持续时间
                            delay:(NSTimeInterval)//动画延迟执行的时间
                          options:(UIViewKeyframeAnimationOptions)//动画的过渡效果
                       animations:^{
                     //执行的关键帧动画
 }
                       completion:^(BOOL finished) {
                     //动画执行提交后的操作
 }];

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

UIViewAnimationOptionLayoutSubviews           //进行动画时布局子控件
UIViewAnimationOptionAllowUserInteraction     //进行动画时允许用户交互
UIViewAnimationOptionBeginFromCurrentState    //从当前状态开始动画
UIViewAnimationOptionRepeat                   //无限重复执行动画
UIViewAnimationOptionAutoreverse              //执行动画回路
UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套动画的执行时间设置
UIViewAnimationOptionOverrideInheritedOptions //不继承父动画设置

UIViewKeyframeAnimationOptionCalculationModeLinear     //运算模式 :连续
UIViewKeyframeAnimationOptionCalculationModeDiscrete   //运算模式 :离散
UIViewKeyframeAnimationOptionCalculationModePaced      //运算模式 :均匀执行
UIViewKeyframeAnimationOptionCalculationModeCubic      //运算模式 :平滑
UIViewKeyframeAnimationOptionCalculationModeCubicPaced //运算模式 :平滑均匀

增加关键帧的方法

[UIView addKeyframeWithRelativeStartTime:(double)//动画开始的时间(占总时间的比例)
                     relativeDuration:(double) //动画持续时间(占总时间的比例)
                           animations:^{
                         //执行的动画
 }];

转场动画

  • 从旧视图到新视图
[UIView transitionFromView:(nonnull UIView *) toView:(nonnull UIView *) duration:(NSTimeInterval) options:(UIViewAnimationOptions) completion:^(BOOL finished) {
                 //动画执行提交后的操作
 }];

在该动画过程中,fromView 会从父视图中移除,并将 toView 添加到父视图中,注意转场动画的作用对象是父视图(过渡效果体现在父视图上)。调用该方法相当于执行下面两句代码:

[fromView.superview addSubview:toView];
[fromView removeFromSuperview];
  • 单个视图的过渡效果
[UIView transitionWithView:(nonnull UIView *)
               duration:(NSTimeInterval)
                options:(UIViewAnimationOptions)
             animations:^{
             //执行的动画
 }
             completion:^(BOOL finished) {
             //动画执行提交后的操作
 }];

二、核心动画

开发步骤

1.使用它需要先添加QuartzCore.framework框架和引入主头文件
2.初始化一个CAAnimation对象,并设置一些动画相关属性
3.通过调用CALayer的addAnimation:forKey:方法增加CAAnimation对象到CALayer中,这样就能开始执行动画了
4.通过调用CALayer的removeAnimationForKey:方法可以停止CALayer中的动画
注:核心动画的执行过程都是在后台操作的,不会阻塞主线程.

CAAnimation继承关系

CAAnimation继承关系图

CAMediaTiming

协议中定义了时间,速度,重复次数等。属性如下:

  • beginTime:动画的开始时间。如果想延迟1s,就设置为CACurrentMediaTime()+2,CACurrentMediaTime()为图层的当前时间
  • duration:动画的持续时间。
  • speed:动画速率,决定动画时间的倍率。当speed为2时,动画时间为设置的duration的1/2。
  • timeOffset:动画时间偏移量。比如设置动画时长为3秒,当设置timeOffset为1.5时,当前动画会从中间位置开始,并在到达指定位置时,走完之前跳过的前半段动画。
  • repeatCount:动画的重复次数。
  • repeatDuration:动画的重复时间。
  • autoreverses:执行的动画按照原动画返回执行。
  • fillMode:决定当前对象在非动画时间段的行为。
    系统提供的包括:
    kCAFillModeRemoved:这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
    kCAFillModeForwards:当动画结束后,layer会一直保持着动画最后的状态
    kCAFillModeBackwards:在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始。
    kCAFillModeBoth:这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态
    注:其实不只是CAAnimation遵循CAMediaTiming协议,CALayer也遵循这个协议,所以在一定程度上我们可以通过控制layer本身的协议属性来控制动画节奏。

CAAnimation

是所有动画对象的父类,是个抽象类,不能直接使用,应该使用它具体的子类。除了CAMediaTiming协议中的方法,增加了CAAnimationDelegate的代理属性等。具体如下:

  • timingFunction:控制动画的显示节奏。
    系统提供的包括:
    kCAMediaTimingFunctionLinear (匀速),kCAMediaTimingFunctionEaseIn (慢进快出),kCAMediaTimingFunctionEaseOut (快进慢出),kCAMediaTimingFunctionEaseInEaseOut (慢进慢出,中间加速),
    kCAMediaTimingFunctionDefault (默认)。
  • delegate:动画代理。
  • removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行后的状态,那就设置为NO,不过还要设置fillMode为kCAFillModeForwards。

CAPropertyAnimation

是CAAnimation的子类,针对对象的可动画属性进行效果的设置,也是个抽象类,不可直接使用。

  • keyPath:CALayer的某个属性名,并通过这个属性的值进行修改,达到相应的动画效果。
  • additive:属性动画是否以当前动画效果为基础,默认为NO。
  • cumulative:指定动画是否为累加效果,默认为NO。
  • valueFunction:此属性配合CALayer的transform属性使用。

CABasicAnimation

基本动画,是CAPropertyAnimation的子类。属性如下:

  • fromValue:keyPath相应属性的初始值。
  • toValue:keyPath相应属性的结束值。
  • byValue:在不设置toValue时,toValue = fromValue + byValue,也就是在当前的位置上增加多少。
核心动画所需值的类型转换

实例如下:

//初始化动画对象
CABasicAnimation * anim = [CABasicAnimation animation];
//设置动画持续时间
anim.duration = 2;
//透明度
anim.keyPath = @"opacity";
//初始值
anim.fromValue = @(1.0f);
//结束值
anim.toValue = @(0.3f);
//添加动画
[self.yellowIV.layer addAnimation:anim forKey:nil];

CASpringAnimation

带有初始速度以及阻尼指数等物理参数的属性动画。属性如下:

  • mass:质量,影响惯性,默认为1。
  • stiffness:劲度系数,默认为100。
  • damping:阻尼系数,默认为10。
  • initialVelocity:初始速度,可正可负,方向不同,默认为0。
  • settlingDuration:结算时间,根据上述参数计算出的预计时间,比较准确。
    实例如下:
//初始化CASpringAnimation对象,并设置keyPath
CASpringAnimation *anim = [CASpringAnimation animationWithKeyPath:@"position"];
//设置质量
anim.mass = 5.f;
//设置劲度系数
anim.stiffness = 120.f;
//设置阻尼系数
anim.damping = 8.f;
//设置初始速度
anim.initialVelocity = 2.f;
//向下平移200
anim.byValue = [NSValue valueWithCGPoint:CGPointMake(0, 200)];
//设置动画时间,使用参数计算出的时间
anim.duration = anim.settlingDuration;
//添加动画
[self.yellowIV.layer addAnimation:anim forKey:@"spring"];

CAKeyframeAnimation

同样通过keyPath对应属性进行控制,但它可以通过values或者path进行多个阶段的控制。属性如下:

  • values:关键帧组成的数组,动画会依次显示其中的每一帧。
  • path:关键帧路径,动画进行的要素,优先级比values高,但是只对CALayer的anchorPoint和position起作用。
  • keyTimes:每一帧对应的时间,其取值范围为0到1.0,如果不设置,则各关键帧平分设定时间。
  • timingFunctions:每一帧对应的动画节奏。
  • calculationMode:动画的运算模式,系统提供了以下几种模式:
    kCAAnimationLinear:连续
    kCAAnimationDiscrete:离散
    kCAAnimationPaced:均匀执行
    kCAAnimationCubic:平滑
    kCAAnimationCubicPaced:平滑均匀
  • tensionValues:动画张力控制。
  • continuityValues:动画连续性控制。
  • biasValues:动画偏差率控制。
  • rotationMode:动画沿路径旋转方式,系统提供了两种模式:
    kCAAnimationRotateAuto:
    kCAAnimationRotateAutoReverse:

实例如下:

//初始化CAKeyframeAnimation对象,并设置keyPath
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//设置动画时间,使用参数计算出的时间
anim.duration = 2.f;
//设置路径
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2-100, 200, 200)];
anim.path = path.CGPath;
//设置关键帧
NSValue *v1 = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
NSValue *v2 = [NSValue valueWithCGPoint:CGPointMake(200, 150)];
NSValue *v3 = [NSValue valueWithCGPoint:CGPointMake(250, 400)];
NSValue *v4 = [NSValue valueWithCGPoint:CGPointMake(100, 250)];
anim.values = @[v1,v2,v3,v4];
//动画运算模式
anim.calculationMode = kCAAnimationCubicPaced;
//沿路径旋转方式
anim.rotationMode = kCAAnimationRotateAutoReverse;
//添加动画
[self.yellowIV.layer addAnimation:anim forKey:@"keyFrames"];

CATransition

是CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。属性如下:

  • type:转场动画类型。
  • subtype:转场动画方向。
  • startProgress:动画起点进度(整体的百分比)。
  • endProgress:动画终点进度(整体的百分比)。
  • filter:自定义转场。

实例如下:

//初始化CATransition对象
CATransition *anim = [CATransition animation];
//转场类型
anim.type = kCATransitionPush;
//动画执行时间
anim.duration = 2.f;
//动画执行方向
anim.subtype = kCATransitionFromLeft;
//添加动画
[self.yellowIV.layer addAnimation:anim forKey:nil];

CAAnimationGroup

动画组,方便对于多动画的统一控制管理。

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

实例如下:

//创建旋转动画对象
CABasicAnimation *retate = [CABasicAnimation animation];
//旋转属性
retate.keyPath = @"transform.rotation";
//角度
retate.toValue = @(M_PI);
    
//创建缩放动画对象
CABasicAnimation *scale = [CABasicAnimation animation];
//缩放属性
scale.keyPath = @"transform.scale";
//缩放比例
scale.toValue = @(0.0);
    
//初始化CAAnimationGroup对象
CAAnimationGroup *group = [CAAnimationGroup animation];
//添加到动画组当中
group.animations = @[retate,scale];
//执行动画时间
group.duration = 2.f;
//添加动画
[self.yellowIV.layer addAnimation:group forKey:nil];

ps:想了解更多的核心动画知识,请阅读ios核心动画高级技巧

参考:完整项目资料下载

你可能感兴趣的:(iOS中的动画)