毋庸置疑的:在iOS开发中,制作动画效果是最让开发者享受的环节之一。一个设计严谨、精细的动画效果能给用户耳目一新的效果,吸引他们的眼光 —— 这对于app而言是非常重要的。

本文作为动画文集的第一篇,最开始是想做个qq下拉刷新的水滴动画的制作讲解,但这几天研读《iOS Animations by Tutorials》一书,对iOS动画开发有了更为深刻的了解,于是决定动画篇将从UIView动画开始讲起,以后还会有Layer、Transitioning等在内的动画,希望本文能抛砖引玉,带给大家不一样的理解,下面送上一张书中demo的效果图。购买书籍

动效

先放上本文demo:点这
ps:本文属于新手向的动画入门文章

从登录动画说起


很长一段时间以来,我都在基于CALayer层进行动画实现,却忽略了UIKit提供给我们的动画接口。这些接口函数足够的强大并且十分的灵活,足以满足我们开发中大部分的动画需求。

在我们了解这些强大的接口前,我们先来看看第一个效果:在用户打开app要进行登录的时候,账户和密码输入框从屏幕的左边进入,接着登录按钮出现。

界面动画

在这段动画之中发生的最为明显的事情就是两个文本框的位置变化,在动画开始之前,两个文本框的位置应该是在屏幕的左边,而下方的按钮现在是隐藏状态(设置alpha)

动画开始前

因此,这个动画之中发生的事情,我们可以用概括为下面的代码:

self.userName.center.x += offset;    //userName进入
self.password.center.x += offset;    //password进入
self.login.alpha = 1;                //显示登录按钮

既然已经知道了我们的动画发生了什么,接着就可以使用UIKit的动画API让我们的动画活起来了

//设置文本框初始位置为屏幕左侧
CGPoint accountCenter = self.userName.center;
CGPoint psdCenter = self.password.center;
accountCenter.x -= 200;
pasCenter.x -= 200;
self.userName.center = accountCenter;
self.password.center = psdCenter;//还原中心坐标
accountCenter.x += 200;
psdCenter.x += 200;
[UIView animateWithDuration: 0.5 animations: ^{self.userName.center = accountCenter;self.password.center = passwordCenter;self.login.alpha = 1;
} completion: nil];

在UIKit中,系统提供了animate标题打头的属于UIView的类方法让我们可以轻松的制作动画效果,每一个这样的类方法提供了名为animationsblock代码块,这些代码会在方法调用后立刻或者延迟一段时间以动画的方式执行。此外,所有这些API的第一个参数都是用来设置动画时长的。

viewDidAppear:中运行这段代码,你会看到文本框从左侧滑动,按钮也渐变显示出来的,但是跟我们要的结果不太一样 —— 三个动画没有错开,效果并不那么的好看。我们希望密码框能在账户文本框滑动后的一段时间后再出现,按钮同样也需要晚一些显示。所以,我们需要使用下面的方法来实现这个效果:

[UIView animateWithDuration: 0.5 delay: 0.35 options: UIViewAnimationOptionCurveEaseInOut animations: ^{self.password.center = passwordCenter;
} completion: ^(BOOL finished) {[UIView animateWithDuration: 0.2 animations: ^{self.login.alpha = 1;}];
}];

这个方法看起来非常的熟悉,相比上面的方法这里多了几个参数来高度定制我们的动画:

  • duration:  动画时长

  • delay:  决定了动画在延迟多久之后执行

  • options:用来决定动画的展示方式,接下来会进行讲解

  • animations:转化成动画表示的代码

  • completion:动画结束后执行的代码块

在上面的代码中,密码输入框在延后0.35秒之后开始从左侧出来,在持续0.5秒的动画之后,开始渐变显示按钮,然后动画完成。

可实现动画的属性


现在你已经可以制作简单的动画了,但要记住:不是所有修改属性的操作放到animations代码块中都是变成动画实现的 —— 不管你怎么修改一个视图的tag,或者是delegate。因此,可实现动画的属性必定会导致视图的重新渲染。
这些可以生成动画的属性大致可以分成这么三类:坐标尺寸视图显示形态变化

坐标尺寸类

  • bounds:修改这个属性会结合center属性重新计算frame。建议通过这个属性修改尺寸

  • frame:修改这个属性通常会导致视图形变的同时也发生移动,然后会重新设置centerbounds属性

  • center: 设置后视图会移动到一个新位置,修改后会结合bounds重新计算frame

    尺寸修改

视图显示类

  • backgroundColor: 修改这个属性会产生颜色渐变过渡的效果,本质上是系统不断修改了tintColor来实现的

  • alpha:修改这个属性会产生淡入淡出的效果

  • hidden:修改这个属性可以制作翻页隐藏的效果

    修改透明度

形态变化类

  • transform:修改这个属性可以实现旋转、形变、移动、翻转等动画效果,其通过矩阵运算的方式来实现,因此更加强大

    旋转

动画参数


上面我们使用到的动画方法中有一个重要的参数options,它能让你高度的自定义动画效果。下面展示这个参数类型的值集合,你可以通过结合不同的参数来实现自己的动画:

  • Repeating

     UIViewAnimationOptionRepeat       //动画循环执行UIViewAnimationOptionAutoreverse  //动画在执行完毕后会反方向再执行一次

    我们将这两个参数传入到上面密码框出现动画中,看看会有什么效果(不同的参数使用|操作符一起传入)

     [UIView animateWithDuration: 0.5 delay: 0.35 options: UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat animations: ^{self.password.center = passwordCenter;} completion: ^(BOOL finished) {[UIView animateWithDuration: 0.2 animations: ^{self.login.alpha = 1;}];}];

    重复的动画

    我们可以看到密码框在不断的循环进入屏幕,反方向退出屏幕这个操作,并且登录按钮也始终没有渐变出现。由此可以知道UIViewAnimationOptionRepeat参数不仅是让动画循环播放,并且还导致了completion的回调永远无法执行。

  • Easing
    我们都知道,一个好的动画应该更符合我们认知的规则。比如,任何事物都不能突然间的开始移动和停下,像车辆启动和停止都有一个加速和减速的过程。

    汽车的加速减速.png

    为了让动画更具符合我们的认知,系统同样提供了类似的效果的参数给我们使用:

      UIViewAnimationOptionCurveEaseInOut   //先加速后减速,默认UIViewAnimationOptionCurveEaseIn      //由慢到快UIViewAnimationOptionCurveEaseOut     //由快到慢UIViewAnimationOptionCurveLinear      //匀速

    我在demo上创建了四个橙色的UIView,分别传入这四个不同的参数,然后让这四个view在同一时间y轴上向上移动。

    [self animatedView: _view1];
    [self animatedView: _view2];
    [self animatedView: _view3];
    [self animatedView: _view4];//y轴上移动视图上升250
    - (void)animatedView: (UIView *)view
    {[UIView animateWithDuration: 0.5 delay: 0 options: UIViewAnimationOptionCurveLinear animations: ^{CGPoint center = view.center;center.y -= 250;view.center = center;} completion: nil];
    }

    四种线性速度表示

    在模拟器运行状态下,点击上面的菜单栏 DEBUG -> Slow Animation 或者快捷键 command + T,这会放慢我们app的动画运行速度(demo在6p的模拟器上运行)。
    在减速环境下,我们看到四个view的速度变化如下:
    1、逐渐加速。EaseIn
    2、先加速,后减速。EaseInOut
    3、速度领先,然后减速。EaseOut
    4、匀速运动。Linear
    运行最开始的登录动画,放慢模拟器的动画速度,你会看到默认情况下使用的EaseInOut参数使得密码框在接近结束点的时候出现了明显的减速动画。

  • Transitioning
    除了上面提到的这些效果,在视图、图片切换的时候,我们还能通过传入下面的这些参数来实现一些特殊的动画效果。

      UIViewAnimationOptionTransitionNone            //没有效果,默认UIViewAnimationOptionTransitionFlipFromLeft    //从左翻转效果UIViewAnimationOptionTransitionFlipFromRight   //从右翻转效果UIViewAnimationOptionTransitionCurlUp          //从上往下翻页UIViewAnimationOptionTransitionCurlDown        //从下往上翻页UIViewAnimationOptionTransitionCrossDissolve   //旧视图溶解过渡到下一个视图UIViewAnimationOptionTransitionFlipFromTop     //从上翻转效果UIViewAnimationOptionTransitionFlipFromBottom  //从上翻转效果

    那么这些参数使用的时机是什么时候呢?我们来看看这么一段代码:

    [UIView transitionWithView: firstPV duration: 0.5 options: UIViewAnimationOptionTransitionFlipFromLeft animations: ^{[firstPV flipCard];
    } completion: ^(BOOL finished) {isAnimating = NO;
    }];- (void)flipCard
    {if (isfliped) {self.image = [UIImage imageNamed: @"flipPicBG.png"];isfliped = NO;} else {self.image = [UIImage imageNamed: [NSString stringWithFormat: @"flipPic%d.png", type]];isfliped = YES; }
    }

    这段代码中我改变了一个UIImageView的图片显示,同样用了一个动画的方式表现。这里用到了一个新的动画API方法,transitionWithView: duration: options: animations: completion:,这个方法跟上面的animateWithDuration系列方法相比多了一个UIView类型的参数,这个参数接收的对象作为动画的作用者。这段代码是我以前做的一个翻卡匹配的小游戏,点击之后的动画效果如下:

    翻卡匹配小游戏

    在模拟器下使用command+T放慢了动画的速度之后,我截取了翻转的四张图片:

    慢动作翻转

    在我们切换图片的时候,原有的图片会基于视图中心位置进行x轴上的翻转,为了达到更逼真的效果,系统还为我们在切换中加上了阴影效果(ps: 再次要说明的是,transition的动画你应该只用在视图的切换当中 —— 你不会在移动中产生任何transition效果的)

弹簧动画


恭喜你,你已经可以使用UIKit的动画接口制作精美的动画了,通过组合不同的options参数你可以制作真实的动画。但是,我们总是能做的更多,比如一个弹簧被用力压扁,当松开手的时候会反复弹动。使用上面的方式纵然可以实现这样的动画,但代码量复杂,也基本无复用性可言,可想而知会是糟糕的代码。因此,我们需要其他的动画方式,系统也正好提供了这样的一种动画供我们使用:

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion

照例科普一下额外的参数信息:

  • dampingRatio:速度衰减比例。取值范围0 ~ 1,值越低震动越强

  • velocity:初始化速度,值越高则物品的速度越快

当一个圆角按钮高速移动的进入界面中,接着狠狠的震动,这绝对会狠狠地吸引住你的眼球。比如我尝试着让某个UICollectionView的分类按钮从屏幕下方弹入视图的时候;又或者我让这个小球弹到右下角,以提示用户该如何操作:

小球弹出效果

这效果非常的棒,在看到这些小圆球之后,你本能的会想要去点击这些按钮,而这些小球弹出的动画仅仅需要下面这么几句代码:

CGPoint center = cell.center;
CGPoint startCenter = center;
startCenter.y += LXD_SCREEN_HEIGHT;
cell.center = startCenter;[UIView animateWithDuration: 0.5 delay: 0.35 * indexPath.item usingSpringWithDamping: 0.6 initialSpringVelocity: 0 options: UIViewAnimationOptionCurveLinear animations: ^{cell.center = center;
} completion: nil];

除了这段弹出的代码,在小球被点击的时候,还会产生一个弹到右下角的动画,然后从左侧弹出列表。这非常的酷,因为不用额外的提示,用户会很自然的知道该怎么回到分组的界面 —— 点击一下右下角的圆形按钮。这是非常重要的,我们的动画应该不仅仅只是为了让界面更加的优雅漂亮,还应该能用以减少用户学习使用app的成本,这些都是动画的追求。

最后

相比起PC端的粗糙,移动端的应用需要更加精致,精致复杂的动画都是源于一个个简单的动画组合而成的。本文作为动画篇的第一篇博客,目的是为了从最简单的UIView动画讲起,慢慢的拓展其它的动画,也希望能起到抛砖引玉的作用。在文章的最后,如果你是iOS动画的初学者,请尝试结合上面提到的知识,为本文最开始的登录demo中添加代码,让按钮从下方渐变显示弹出:

弹出的登录按钮

最后的最后,吐槽一下gitcafe。本来以为托管到gitcafe后个人博客在国内的访问速度会提高,结果今天博客更新了两小时,还显示不出来。

本文demo
转载请注明出处 http://www.cocoachina.com/ios/20160215/15262.html

iOS 开发之动画篇 - 从 UIView 动画说起相关推荐

  1. iOS 开发之动画篇 - Transform和KeyFrame动画

    原文发布于http://www.jianshu.com/p/a071bba99a1b 序言 追求美好是人的天性,这是猿们无法避免的.我们总是追求更为酷炫的实现,如果足够仔细,我们不难发现一个好的动画通 ...

  2. iOS开发系列--让你的应用“动”起来--超详细的ios核心动画介绍

    概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建基础动画.关键帧动画 ...

  3. iOS开发系列--让你的应用“动”起来

    概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建基础动画.关键帧动画 ...

  4. [分享]iOS开发-UI篇:CAlayer层的属性

    iOS开发UI篇-CAlayer层的属性 一.position和anchorPoint 1.简单介绍 CALayer有2个非常重要的属性:position和anchorPoint @property ...

  5. iOS开发之让你的应用“动”起来转写

    在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建基础动画.关键帧动画.动画 ...

  6. iOS开发入门——基础篇一

    文章目录 1. iOS应用生命周期 1.1 应用程序的架构 1.2 iOS应用的5种状态: 1.2.1做一些操作对应的生命周期调用的顺序 1.2.2全面的生命周期执行流程图 1.3 Main函数入口 ...

  7. react-native系列(13)动画篇:Animated动画库和LayoutAnimation布局动画详解

    动画概念了解 流畅.有意义的动画对于APP户体验来说是非常重要的,用RN开发实现动画有三种方法: requestAnimationFrame:称为帧动画,原理是通过同步浏览器的刷新频率不断重新渲染界面 ...

  8. iOS开发---设计素材篇2

    转自http://www.cocoachina.com/applenews/devnews/2013/0117/5562.html 虽然技术是iOS开发的主心骨,但漂亮的界面和素材是吸引人的关键要素. ...

  9. ios开发学习--动画(Animation)效果源码分享--系列教程1

    Genie View        介绍: 实现所谓的genie effect.即点击最小化或删除按钮,视图会被吸进某个地方.         http://ios.itmdc.com/forum.p ...

最新文章

  1. Ubuntu20.04 编译运行apue.3e 避坑指南
  2. 手机操作系统如何实现跨平台开发和使用
  3. $router VS $route
  4. MATLAB无边框输出图像
  5. 亲戚(信息学奥赛一本通-T1389)
  6. Go程序:变量声明、赋值与输出
  7. php url路由入门实例,ThinkPHP URL 路由实例
  8. 被调用的对象已与其客户端断开连接 win10_【完整案例】基于Socket开发TCP传输客户端...
  9. 解决ajax中文乱码问题
  10. Luogu2572 [SCOI2010]序列操作
  11. DB9 串口母对母转接头是个坑
  12. 两个不同网段的局域网如何互通_不同品牌的对讲机如何实现互通?
  13. “马赛克”真能去除了?老司机狂喜!这一神器一键去除!
  14. 设备综合效率OEE:基于数采的OEE优化分析
  15. 功能测试数据测试之错误推测方法
  16. iis服务器响应缓慢,IIS网站加载缓慢怎么办?如何处理?
  17. 包装类、自动装箱/自动拆箱
  18. 谷粒商城开发踩坑及部分知识点大总结
  19. OpenJudge-021:鸣人和佐助
  20. 表单验证与自定义表单验证

热门文章

  1. mysql jpa默认值_Spring JPA-枚举中枚举字段的默认值
  2. 最详细 Spring Boot 入门(-)
  3. android怎么增量编译,Android Transform增量编译
  4. MATLAB对表达式进行降幂排列,MATLAB上机答案.doc
  5. mysql 时间戳截断_列的Mysql时间戳数据被截断
  6. c语言解三元一次方程组_一次二次反比例,一山更比一山高?二次函数三大解析式详解...
  7. c++编程求解二元二次方程组_一道俄罗斯高难度解方程组题,错误率达99%+,中国学霸:确实很难...
  8. asp.net MVC遇到的问题
  9. 优秀Python学习资源收集汇总
  10. 结构体构造函数_Go 语言的数据结构 :栈与队列