iOS 动画使用总结

栏目: C · 发布时间: 5年前

内容简介:以前要做动画方面相关的功能时都是去百度,想着自己也总结下,方便自己记忆和查找,更加深自己对这方面的理解日常开发 UIKIt 层和 Core Animation 层的动画基本可以实现绝大多数需求,并且层级越高 API 的封装程度越高,也越简洁。本文主要讲解 View Animation 和 Core Animation。

前言

以前要做动画方面相关的功能时都是去百度,想着自己也总结下,方便自己记忆和查找,更加深自己对这方面的理解

iOS 图形分层

iOS 动画使用总结

日常开发 UIKIt 层和 Core Animation 层的动画基本可以实现绝大多数需求,并且层级越高 API 的封装程度越高,也越简洁。本文主要讲解 View Animation 和 Core Animation。

UIKit 层

UIView Animation

我们来看看通过 UIView Animation 都可以实现那些动画

iOS 动画使用总结

大小动画(frame改变)

#pragma mark  ---------------------大小动画,frame 改变
- (void)initSizeAnimation {
    CGRect origin = self.showImage.frame;
    CGRect terminal = CGRectMake(SCREEN_W/2-100, SCREEN_H/2-100, 200, 200);
    [UIView animateWithDuration:1 animations:^{
        self.showImage.frame = terminal;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:1 animations:^{
            self.showImage.frame = origin;
        }];
    }];
}

拉伸动画 bounds 改变

#pragma mark ------------------拉伸动画 bounds 改变
- (void)initBoundsAnimation {
    CGRect origin = self.showImage.bounds;
    //拉伸动画基于view的bound改变,只改变宽高,
    CGRect terminal = CGRectMake(0, 0, 200, 150);
    [UIView animateWithDuration:1 animations:^{
        self.showImage.bounds = terminal;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:1 animations:^{
            self.showImage.bounds = origin;
        }];
    }];
}

中心位置动画,改变center

#pragma mark ----------------中心位置动画,改变center
- (void)initCenterAnimation {
    CGPoint origin = self.showImage.center;
    CGPoint terminal = CGPointMake(self.showImage.center.x, self.showImage.center.y-100);
    [UIView animateWithDuration:1 animations:^{
        self.showImage.center = terminal;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:1 animations:^{
            self.showImage.center = origin;
        }];
    }];
}

旋转动画,改变transform

#pragma mark ----------------旋转动画,改变transform
- (void)initTransformAnimation {
    CGAffineTransform origin = self.showImage.transform;
    [UIView animateWithDuration:2 animations:^{
//        self.showImage.transform = CGAffineTransformMakeScale(0.6, 0.6);//缩放
//        self.showImage.transform = CGAffineTransformMakeTranslation(60, -60);//偏移
        self.showImage.transform = CGAffineTransformMakeRotation(4.0f);//旋转
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:2 animations:^{
            self.showImage.transform = origin;
        }];
    }];
}

透明度动画 改变alpha

#pragma mark ----------------透明度动画 改变alpha
- (void)initAlphaAnimation {
    [UIView animateWithDuration:2 animations:^{
        self.showImage.alpha = 0.3;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:2 animations:^{
            self.showImage.alpha = 1;
        }];
    }];
}

转场动画 transition

#pragma mark ----------------转场动画 transition
- (void)initTransitionAnimation {
    [UIView transitionWithView:self.showImage duration:2.0 options:UIViewAnimationOptionTransitionFlipFromTop animations:^{
        
    } completion:^(BOOL finished) {
        [UIView transitionWithView:self.showImage  duration:2  options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{
            
        } completion:^(BOOL finished) {
            
        }];
    }];
}

spring 动画(弹簧效果)(ios7以上)

#pragma mark ----------------spring 动画(弹簧效果)
- (void)initSpringAnimation {
    CGRect origin = self.showImage.frame;
    CGRect terminal = CGRectMake(origin.origin.x+50, origin.origin.y, 150, 150);
    [UIView animateWithDuration:1 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:4 options:UIViewAnimationOptionCurveLinear animations:^{
        self.showImage.frame = terminal;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:1 delay:1 usingSpringWithDamping:0.5 initialSpringVelocity:4 options:UIViewAnimationOptionCurveLinear animations:^{
            self.showImage.frame = origin;
        } completion:^(BOOL finished) {
            
        }];
    }];
}

背景颜色动画

#pragma mark ----------------背景颜色动画 改变 background
- (void)initBackgroundAnimation {
    self.showImage.image = [UIImage imageNamed:@"example1"];
    
    [UIView animateKeyframesWithDuration:6.0 delay:0.f options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{
        [UIView addKeyframeWithRelativeStartTime:0.f relativeDuration:1.0 / 4 animations:^{
            self.showImage.backgroundColor = [UIColor redColor];
        }];
        [UIView addKeyframeWithRelativeStartTime:1.0 / 4 relativeDuration:1.0 / 4 animations:^{
            self.showImage.backgroundColor = [UIColor greenColor];
        }];
        [UIView addKeyframeWithRelativeStartTime:2.0 / 4 relativeDuration:1.0 / 4 animations:^{
            self.showImage.backgroundColor = [UIColor yellowColor];
        }];
        [UIView addKeyframeWithRelativeStartTime:2.0 / 4 relativeDuration:1.0 / 4 animations:^{
            self.showImage.backgroundColor = [UIColor greenColor];
        }];
        [UIView addKeyframeWithRelativeStartTime:1.0 / 4 relativeDuration:1.0 / 4 animations:^{
            self.showImage.backgroundColor = [UIColor whiteColor];
        }];
    } 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  //转场,从下向上旋转翻页

UIViewKeyframeAnimationOptions

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

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

总结

  • UIView 动画主要变化 UIView 自身的属性
  • 一个效果有多种方式实现,通过组合也可以实现比较高级的动画效果

Core Animation

Core Animation是直接作用在 CALayer 上的,iOS 和 Mac OS 都可以使用,Core Animation 的动画过程都是在后台操作的,不会阻塞主线程。

下面是 Core Animation 所涉及的几个类的继承关系

iOS 动画使用总结

  • CAMediaTiming 协议中定义了时间、速度、重复次数等,包含属性:

    • beginTime:设置延时时间
    • duration:持续时间
    • speed:动画速率
    • timeOffset:动画时间偏移量
    • repeatCount:动画的重复次数等
    • repeatDuration:重复时间
    • autoreverses:结束后是否反过来恢复到初始值
    • fillMode:当前对象在非对象时间段的初始值
  • CAAnimation 核心动画基础类,不能直接使用

    • timingFunction -> 控制动画的节奏。系统提供的包括:

      • kCAMediaTimingFunctionLinear (匀速)
      • kCAMediaTimingFunctionEaseIn (慢进快出)
      • kCAMediaTimingFunctionEaseOut (快进慢出)
      • kCAMediaTimingFunctionEaseInEaseOut (慢进慢出,中间加速)
      • kCAMediaTimingFunctionDefault (默认),当然也可通过自定义创建CAMediaTimingFunction
    • delegate -> 代理。
    • emovedOnCompletion -> 是否让图层保持显示动画执行后的状态,默认为YES,也就是动画执行完毕后从涂层上移除,恢复到执行前的状态,如果设置为NO,并且设置fillMode为kCAFillModeForwards,则保持动画执行后的状态。
  • CAPropertyAnimation 属性动画,针对对象的可动画属性进行效果的设置,不可直接使用。

    • keyPath -> CALayer的某个属性名,并通过这个属性的值进行修改,达到相应的动画效果。
    • additive -> 属性动画是否以当前动画效果为基础,默认为NO。
    • cumulative -> 指定动画是否为累加效果,默认为NO。
    • valueFunction -> 此属性配合CALayer的transform属性使用。
  • CABasicAnimation基础动画,通过keyPath对应属性进行控制,需要设置fromValue以及toValue,只能在两个属性间变化。

    • fromValue -> keyPath相应属性的初始值。
    • toValue -> keyPath相应属性的结束值。
    • byValue -> 在不设置toValue时,toValue = fromValue + byValue,也就是在当前的位置上增加多少。
  • CASpringAnimation 带有初始速度以及阻尼指数等物理参数的属性动画。

    • mass -> 小球质量,影响惯性
    • stiffness -> 弹簧的劲度系数
    • damping -> 阻尼系数,地面的摩擦力
    • initialVelocity -> 初始速度,相当于给小球一个初始速度(可正可负,方向不同)
    • settlingDuration -> 结算时间,根据上述参数计算出的预计时间,相对于你设置的时间,这个时间比较准确。
  • CAKeyframeAnimation 关键帧动画,同样通过keyPath对应属性进行控制,但它可以通过values或者path进行多个阶段的控制

    • values -> 关键帧组成的数组,动画会依次显示其中的每一帧
    • path -> 关键帧路径,动画进行的要素,优先级比values高,但是只对CALayer的anchorPoint和position起作用
    • keyTimes -> 每一帧对应的时间,如果不设置,则各关键帧平分设定时间
    • timingFunctions -> 每一帧对应的动画节奏
    • calculationMode -> 动画的计算模式,系统提供了对应的几种模式
    • tensionValues -> 动画张力控制
    • continuityValues -> 动画连续性控制
    • biasValues -> 动画偏差率控制
    • rotationMode -> 动画沿路径旋转方式,系统提供了两种模式。
  • CATransition 转场动画,系统提供了很多酷炫效果

    • type -> 转场动画类型
    • subtype -> 转场动画方向
    • startProgress -> 动画起点进度(整体的百分比)
    • endProgress -> 动画终点进度(整体的百分比)
    • filter -> 自定义转场。
  • CAAnimationGroup 动画组,方便对于多动画的统一控制管理。

    • animations -> 所有动画效果元素的数组。

CABasicAnimation

在一般的应用开发中,基础动画可以满足大部分的开发需求,主要完成对于对象指定动画属性两个Value之间的动画过渡。

下面展示使用 CABasicAnimation 实现 位移、缩放、透明度、旋转、圆角 的核心代码

switch (button.tag) {
        case 0:
            //位移动画
            basicAni = [CABasicAnimation animationWithKeyPath:@"position"];
            //到达位置
//            basicAni.byValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
            basicAni.toValue = [NSValue valueWithCGPoint:CGPointMake(_mainLayer.position.x+100, _mainLayer.position.y+100)];
            break;
        case 1:
            //缩放动画
            basicAni = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
            //到达缩放
            basicAni.toValue = @(0.1f);
            break;
        case 2:
            //透明度动画
            basicAni = [CABasicAnimation animationWithKeyPath:@"opacity"];
            //透明度
            basicAni.toValue=@(0.1f);
            break;
        case 3:
            //旋转动画
            basicAni = [CABasicAnimation animationWithKeyPath:@"transform"];
            //3D
            basicAni.toValue=[NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI_2+M_PI_4, 1, 1, 0)];
            break;
        case 4:
            //圆角动画
            basicAni = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
            //圆角
            basicAni.toValue=@(50);
            break;

CASpringAnimation

CASpringAnimation 是 iOS9引入的动画类,类似于 UIView 的 spring 动画,但是增加的质量,劲度系数等属相的扩展,继承自 CABaseAnimation,用法也比较简单:

#pragma mark -----------------------CASpringAniamtion 
- (void)initSpringAnimation {
    CASpringAnimation *springAni = [CASpringAnimation animationWithKeyPath:@"position"];
    springAni.damping = 2;
    springAni.stiffness = 50;
    springAni.mass = 1;
    springAni.initialVelocity = 10;
    springAni.toValue = [NSValue valueWithCGPoint:CGPointMake(200, 400)];
    springAni.duration = springAni.settlingDuration;
    [_mainLayer addAnimation:springAni forKey:@"springAnimation"];
}

CAKeyframeAnimation

CAKeyframeAnimation和CABasicAnimation一样是CApropertyAnimation的子类,但是CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue)或者添加一个增量数值(byValue),而CAKeyframeAnimation使用values数组可以设置多个关键帧,同时可以利用path可以进行位置或者锚点的动画操作

- (void)initKeyframeAnimation {
    CAKeyframeAnimation *animation = nil;
    if (self.animationIndex == 2) {//晃动
        animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
        animation.duration = 0.3;
        animation.values = @[@(-(4) / 180.0*M_PI),@((4) / 180.0*M_PI),@(-(4) / 180.0*M_PI)];
        animation.repeatCount=MAXFLOAT;
    }else {//曲线位移
        animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:_mainLayer.position];
        [path addCurveToPoint:CGPointMake(300, 500) controlPoint1:CGPointMake(100, 400) controlPoint2:CGPointMake(300, 450)];
        animation.path = path.CGPath;
        animation.duration = 1;
        animation.removedOnCompletion = NO;
        animation.fillMode = kCAFillModeForwards;
    }
    [_mainLayer addAnimation:animation forKey:@"keyFrameAnimation"];
}

CATransition

转场动画是一种显示样式向另一种显示样式过渡的效果,系统给出的效果也很多,不过谨慎使用私有API,防止被拒的悲剧.

具体有以下效果:

  • cube 方块
  • suckEffect 三角
  • rippleEffect 水波抖动
  • pageCurl 上翻页
  • pageUnCurl 下翻页
  • oglFlip 上下翻转
  • cameraIrisHollowOpen 镜头快门开
  • cameraIrisHollowClose 镜头快门开
- (void)initCATransitionAnimation {
    CATransition *transition = [CATransition animation];
    transition.type = @"rippleEffect";
    transition.subtype = kCATransitionFromLeft;
    transition.duration = 1;
    _mainLayer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"example"].CGImage);
    [_mainLayer addAnimation:transition forKey:@"transtion"];
}

CAAnimationGroup

在我们实际开发中,我们可能需要更加复杂的复合运动,那么需要给图层加多个动画,动画组也就应运而生,创建动画组也很简单,首先创建单个动画,然后将创建的多个动画添加到动画组,最后将动画组添加图层上就可以啦。

- (void)initAnimationGroup {
    //晃动动画
    CAKeyframeAnimation *keyFrameAni = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
    keyFrameAni.values = @[@(-(4) / 180.0*M_PI),@((4) / 180.0*M_PI),@(-(4) / 180.0*M_PI)];
    //每一个动画可以单独设置时间和重复次数,在动画组的时间基础上,控制单动画的效果
    keyFrameAni.duration = 0.3;
    keyFrameAni.repeatCount= MAXFLOAT;
    keyFrameAni.delegate = self;
//    keyFrameAni.removedOnCompletion = NO;
//    keyFrameAni.fillMode = kCAFillModeForwards;
    //位移动画
    CABasicAnimation *basicAni = [CABasicAnimation animationWithKeyPath:@"position"];
    //到达位置
    basicAni.byValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
    //
    basicAni.duration = 1;
    basicAni.repeatCount = 1;
    //
    basicAni.removedOnCompletion = NO;
    basicAni.fillMode = kCAFillModeForwards;
    //设置代理
    basicAni.delegate = self;
    //动画时间
    basicAni.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    CAAnimationGroup *aniGroup = [CAAnimationGroup animation];
    aniGroup.animations = @[keyFrameAni,basicAni];
    aniGroup.autoreverses = YES;
    //动画的表现时间和重复次数由动画组设置的决定
    aniGroup.duration = 2;
    aniGroup.repeatCount= 3;
    //使动画结束后停留在结束位置
//    aniGroup.autoreverses = NO;
//    aniGroup.removedOnCompletion = NO;
//    aniGroup.fillMode = kCAFillModeForwards;
    //
    [_mainLayer addAnimation:aniGroup forKey:@"groupAnimation"];
    
}

总结

Core Animation 给我们展示的只是假象;layer 的 frame、bounds、position 不会在动画完毕后发生改变;

UIView 封装的动画会真实修改 view 的一些属性。

本文总结的内容个人感觉还是比较浅的,但还是能满足日常开发要求的,当然一些要求比较高的,还需要大家对每个动画类进行深入的研究。

最后附上本文的 Demo 地址 : animation


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web Design Index 7

Web Design Index 7

Pepin Press / PEPIN PRESS / 20070501 / TWD$1000.00

《網頁設計索引》年刊自2000年誕生起現已發展成同行業最重要的出版物之一,每年都會對網頁設計的最新趨勢給予準確概述。網站可簡單到只有一頁,也可以設計為具有最新數位性能的複雜結構。《網頁設計索引》的篩選標準是根據設計品質、創意及效率-而不管複雜程度如何。因此在本書中你可以找到所有可能的樣式和風格的實例。 每輯《網頁設計索引》都展示了1002個精采的網頁 同時提供了每個網頁的URL。網頁設計和編......一起来看看 《Web Design Index 7》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具