iOS动画解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: iOS引入动画效果可以使我们的软件得到更好的用户体验,因此动画的深入研究无疑对于开发者一个很好的加分项。常见的iOS对动画的操作分为两类:CALayer层的操作UIView的操作 二者有何区别UIView里面包含有一个CALayer层UIView之所以能够在屏幕上显示出来,完全因为其内部拥有一个CALayer层CALayer层的操作更底层更轻量级、性能更高。

iOS引入动画效果可以使我们的软件得到更好的用户体验,因此动画的深入研究无疑对于开发者一个很好的加分项。

常见的iOS对动画的操作分为两类:

  1. CALayer层的操作

  2. UIView的操作

二者有何区别

  1. UIView里面包含有一个CALayer层

  2. UIView之所以能够在屏幕上显示出来,完全因为其内部拥有一个CALayer层

  3. CALayer层的操作更底层更轻量级、性能更高。

  4. UIView动画执行完毕之后不会反弹,而CALayer动画改变layer的状态位置,出现假象的改变,其实实际位置并没有改变

开发时如何选择二者:

  1. 每个UIView的操作其实是对CALayer层的封装,比较简单,优先选择UIView动画操作。

  2. 操作CALayer层更直接,能实现UIView所不能实现的功能

UIView动画

一、首尾式动画(经典的不能再经典啦)

    [UIView beginAnimations:nil context:nil] ;
    //需要执行动画的核心代码
     //设置动画执行时间
     [UIView setAnimationDuration:2.0];
     //设置代理
     [UIView setAnimationDelegate:self];
     //设置动画执行完毕调用的事件
     [UIView setAnimationDidStopSelector:@selector(didStopAnimation)];
    self.customView.center=CGPointMake(200, 300);
    [UIView commitAnimations];
+ (void)setAnimationDelegate:(id)delegate     设置动画代理对象,当动画开始或者结束时会发消息给代理对象

+ (void)setAnimationWillStartSelector:(SEL)selector   当动画即将开始时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector

+ (void)setAnimationDidStopSelector:(SEL)selector  当动画结束时,执行delegate对象的selector,并且把beginAnimations:context:中传入的参数传进selector

+ (void)setAnimationDuration:(NSTimeInterval)duration   动画的持续时间,秒为单位

+ (void)setAnimationDelay:(NSTimeInterval)delay  动画延迟delay秒后再开始

+ (void)setAnimationStartDate:(NSDate *)startDate   动画的开始时间,默认为now

+ (void)setAnimationCurve:(UIViewAnimationCurve)curve  动画的节奏控制

+ (void)setAnimationRepeatCount:(float)repeatCount  动画的重复次数

+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses  如果设置为YES,代表动画每次重复执行的效果会跟上一次相反

+ (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache  设置视图view的过渡效果, transition指定过渡类型, cache设置YES代表使用视图缓存,性能较好

二、block动画(依旧也经典)

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

duration:动画的持续时间
delay:动画延迟delay秒后开始
options:动画的节奏控制
animations:将改变视图属性的代码放在这个block中
completion:动画结束后,会自动调用这个block
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

duration:动画的持续时间
view:需要进行转场动画的视图
options:转场动画的类型
animations:将改变视图属性的代码放在这个block中
completion:动画结束后,会自动调用这个block

+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion

duration:动画的持续时间

options:转场动画的类型

animations:将改变视图属性的代码放在这个block中

completion:动画结束后,会自动调用这个block
options参数的详细的枚举

typedef NS_OPTIONS(NSUInteger, UIViewAnimationOptions) {
    UIViewAnimationOptionLayoutSubviews            = 1 <<  0,
    UIViewAnimationOptionAllowUserInteraction      = 1 <<  1, // turn on user interaction while animating
    UIViewAnimationOptionBeginFromCurrentState     = 1 <<  2, // start all views from current value, not initial value
    UIViewAnimationOptionRepeat                    = 1 <<  3, // repeat animation indefinitely
    UIViewAnimationOptionAutoreverse               = 1 <<  4, // if repeat, run animation back and forth
    UIViewAnimationOptionOverrideInheritedDuration = 1 <<  5, // ignore nested duration
    UIViewAnimationOptionOverrideInheritedCurve    = 1 <<  6, // ignore nested curve
    UIViewAnimationOptionAllowAnimatedContent      = 1 <<  7, // animate contents (applies to transitions only)
    UIViewAnimationOptionShowHideTransitionViews   = 1 <<  8, // flip to/from hidden state instead of adding/removing
    UIViewAnimationOptionOverrideInheritedOptions  = 1 <<  9, // do not inherit any options or animation type

    UIViewAnimationOptionCurveEaseInOut            = 0 << 16, // default
    UIViewAnimationOptionCurveEaseIn               = 1 << 16,
    UIViewAnimationOptionCurveEaseOut              = 2 << 16,
    UIViewAnimationOptionCurveLinear               = 3 << 16,

    UIViewAnimationOptionTransitionNone            = 0 << 20, // default
    UIViewAnimationOptionTransitionFlipFromLeft    = 1 << 20,
    UIViewAnimationOptionTransitionFlipFromRight   = 2 << 20,
    UIViewAnimationOptionTransitionCurlUp          = 3 << 20,
    UIViewAnimationOptionTransitionCurlDown        = 4 << 20,
    UIViewAnimationOptionTransitionCrossDissolve   = 5 << 20,
    UIViewAnimationOptionTransitionFlipFromTop     = 6 << 20,
    UIViewAnimationOptionTransitionFlipFromBottom  = 7 << 20,
} NS_ENUM_AVAILABLE_IOS(4_0);

CALayer层动画

CALayer的两个属性:

  1. position位置(原点为父类的(0,0))

  2. anchorPoint 锚点(默认原点在自身长和宽各一半的交点(0.5,0.5))

什么是隐式动画

简单说,每个控件都有一个自带的CALayer层,这个层称为根层,与之相对于的就是非根层,非根层的的属性改变就会默认引发动画,这样的动画就可以称为隐式动画

若项目需求要求不能够动画效果,如何关闭隐式动画?

    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    //......这里修改你想修改的Layer属性就不会产生默认的隐式动画
    [CATransaction commit];

Layer层的动画分类这里写图片描述

CAAnimation是所有动画类的父类,它和CAPropertyAnimation不能直接使用,应该使用它的子类CABasicAnimation、CAKeyframeAnimation、CATransition、CAAnimationGroup

CABasicAnimation基础动画

  • fromValue:keyPath相应属性值的初始值

  • toValue:keyPath相应属性的结束值

  • byValue : 增加多少值(注意对比toValue的意思)

  • keyPath内容是CALayer的可动画Animation属性

 // 1.创建动画对象
    CABasicAnimation *anim = [CABasicAnimation animation];

    // 2.设置动画对象
    // keyPath决定了执行怎样的动画, 调整哪个属性来执行动画
    anim.keyPath = @"transform.translation.x";
    anim.toValue = @(100);
    //执行的时间
    anim.duration = 2.0;
    //加入下面两行,当动画结束时,layer所在的位置不会回到初始位置
    anim.removedOnCompletion = NO;
    anim.fillMode = kCAFillModeForwards;
     // 3.添加动画
    [self.layer addAnimation:anim forKey:nil];

CAKeyframeAnimation关键帧动画

CAKeyframeAnimation是CABasicAnimation的升级版,CABasicAnimation只能改变一组属性动画就停止了,而CAKeyframeAnimation可以运行关于一个属性的一个数组的数据(这里需要特别注意是同一个属性的一组数据)

  • values:所有的值

  • path:路线

  • keyTimes:可以为对应的关键帧制定对应的时间点,取值范围是0到1.0

注意:path和values二者是相互排斥的,二者选取一个即可

values例子:

        CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
        anim.keyPath = @"transform.rotation";
        anim.values = array;
        anim.duration = 0.25;
        // 动画的重复执行次数
        anim.repeatCount = MAXFLOAT;
          // 保持动画执行完毕后的状态
        anim.removedOnCompletion = NO;
        anim.fillMode = kCAFillModeForwards;
        [self.redView.layer addAnimation:anim forKey:nil];

path例子:

CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];

    anim.keyPath = @"position";
    anim.removedOnCompletion = NO;
    anim.fillMode = kCAFillModeForwards;
    anim.duration = 2.0;

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddEllipseInRect(path, NULL, CGRectMake(100, 100, 200, 200));
    anim.path = path;
    CGPathRelease(path);

    // 设置动画的执行节奏
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    anim.delegate = self;

    [self.redView.layer addAnimation:anim forKey:nil];

CAAnimationGroup 动画组

我们上面两个动画类都是只能对同一个属性进行修改产生动画,而不能同时修改两个参数属性。所有就引入了CAAnimationGroup动画组
最经典的莫过于:边旋转边缩放边移动的动画效果,其实就是前面的基础动画加入到动画组形成的

// 1.创建旋转动画对象
    CABasicAnimation *rotate = [CABasicAnimation animation];
    rotate.keyPath = @"transform.rotation";
    rotate.toValue = @(M_PI);

    // 2.创建缩放动画对象
    CABasicAnimation *scale = [CABasicAnimation animation];
    scale.keyPath = @"transform.scale";
    scale.toValue = @(0.0);

    // 3.平移动画
    CABasicAnimation *move = [CABasicAnimation animation];
    move.keyPath = @"transform.translation";
    move.toValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];

    // 4.将所有的动画添加到动画组中
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = @[rotate, scale, move];
    group.duration = 2.0;
    group.removedOnCompletion = NO;
    group.fillMode = kCAFillModeForwards;

    [self.myvie.layer addAnimation:group forKey:nil];

CATransition转场动画

提供移除屏幕和移入屏幕的动画效果

   /** 转场动画代码 */
    // 创建转场动画对象
    CATransition *anim = [CATransition animation];

    // 设置转场类型
    anim.type = @"pageCurl";

    // 设置动画的方向
    anim.subtype = kCATransitionFromLeft;

    anim.duration = 3;

    [_imageV.layer addAnimation:anim forKey:nil];
  • type:动画过渡类型
  • subtype:动画过渡方向

附一张type参照表

这里写图片描述

+(void)transitionWithView:(UIView*)view duration:(NSTimeInterval)duration options:
(UIViewAnimationOptions)options 
animations:(void(^)(void))animations 
completion:(void(^)(BOOLfinished))completion;
  • duration:动画的持续时间
  • view:需要进行转场动画的视图
  • options:转场动画的类型
  • animations:将改变视图属性的代码放在这个block中
  • completion:动画结束后,会自动调用这个block
+ (void)transitionFromView:(UIView*) fromView 
toView:(UIView*) toViewduration:(NSTimeInterval)durationoptions:(UIViewAnimationOptions) options 
completion:(void(^)(BOOLfinished))completion;
  • duration:动画的持续时间
  • options:转场动画的类型
  • animations:将改变视图属性的代码放在这个block中
  • completion:动画结束后,会自动调用这个block

动画代理

动画也是存在代理的,实现代理可以在动画开始的时候调用和动画结束的时候调用的时候做些事情

 anim.delegate = self;
 #pragma mark 动画开始的时候调用
- (void)animationDidStart:(CAAnimation *)anim
{

}
#pragma mark 动画结束的时候调用
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{

}
相关文章
|
29天前
|
Java 开发工具 Android开发
Android与iOS开发环境搭建全解析####
本文深入探讨了Android与iOS两大移动操作系统的开发环境搭建流程,旨在为初学者及有一定基础的开发者提供详尽指南。我们将从开发工具的选择、环境配置到第一个简单应用的创建,一步步引导读者步入移动应用开发的殿堂。无论你是Android Studio的新手还是Xcode的探索者,本文都将为你扫清开发道路上的障碍,助你快速上手并享受跨平台移动开发的乐趣。 ####
|
21天前
|
存储 安全 数据安全/隐私保护
深入解析iOS 14隐私保护功能:用户数据安全的新里程碑
随着数字时代的到来,个人隐私保护成为全球关注的焦点。苹果公司在最新的iOS 14系统中引入了一系列创新的隐私保护功能,旨在为用户提供更透明的数据使用信息和更强的控制权。本文将深入探讨iOS 14中的几项关键隐私功能,包括App跟踪透明性、简化的隐私设置以及增强的系统安全性,分析它们如何共同作用以提升用户的隐私保护水平。
71 3
|
22天前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
26天前
|
数据安全/隐私保护 iOS开发 开发者
iOS 14隐私保护新特性深度解析####
随着数字时代的到来,隐私保护已成为全球用户最为关注的问题之一。苹果在最新的iOS 14系统中引入了一系列创新功能,旨在增强用户的隐私和数据安全。本文将深入探讨iOS 14中的几大隐私保护新特性,包括App跟踪透明度、剪贴板访问通知和智能防追踪功能,分析这些功能如何提升用户隐私保护,并评估它们对开发者和用户体验的影响。 ####
|
1月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户点击按钮时,按钮将从圆形变为椭圆形,颜色从蓝色渐变到绿色;释放按钮时,动画以相反方式恢复。通过UIView的动画方法和弹簧动画效果,实现平滑自然的过渡。
59 1
|
29天前
|
开发框架 Dart Android开发
安卓与iOS的跨平台开发:Flutter框架深度解析
在移动应用开发的海洋中,Flutter作为一艘灵活的帆船,正引领着开发者们驶向跨平台开发的新纪元。本文将揭开Flutter神秘的面纱,从其架构到核心特性,再到实际应用案例,我们将一同探索这个由谷歌打造的开源UI工具包如何让安卓与iOS应用开发变得更加高效而统一。你将看到,借助Flutter,打造精美、高性能的应用不再是难题,而是变成了一场创造性的旅程。
|
2月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
【10月更文挑战第18天】本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户按下按钮时,按钮将从圆形变为椭圆形并从蓝色渐变为绿色;释放按钮时,动画恢复原状。通过UIView的动画方法和弹簧动画效果,实现平滑自然的动画过渡。
62 5
|
1月前
|
安全 5G Android开发
安卓与iOS的较量:技术深度解析
【10月更文挑战第24天】 在移动操作系统领域,安卓和iOS无疑是两大巨头。本文将深入探讨这两个系统的技术特点、优势和不足,以及它们在未来可能的发展方向。我们将通过对比分析,帮助读者更好地理解这两个系统的本质和内涵,从而引发对移动操作系统未来发展的深思。
52 0
|
1月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
8天前
|
iOS开发 开发者 MacOS
深入探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】 本文将带领读者深入了解Apple最新推出的SwiftUI框架,这一革命性的用户界面构建工具为iOS开发者提供了一种声明式、高效且直观的方式来创建复杂的用户界面。通过分析SwiftUI的核心概念、主要特性以及在实际项目中的应用示例,我们将展示如何利用SwiftUI简化UI代码,提高开发效率,并保持应用程序的高性能和响应性。无论你是iOS开发的新手还是有经验的开发者,本文都将为你提供宝贵的见解和实用的指导。
91 66

推荐镜像

更多