iOS UIView动画实践(一):揭开Animation的神秘面纱

前言

在一个看脸的社会中,不论什么事物,长得好看总是能多吸引一些目光。App同样不例外,一款面相不错的App就算功能已经被轮子千百遍,依然会有人买账,理由就是看得顺眼,于是平面设计人员越来越被重视。白驹过隙,斗转星移,人们已然不满足于静态的美感,于是动态的用户体验应运而生,平面设计人员捉襟见肘,是我们程序员出马的时候了。

这篇文章是UIView Animation的第一篇,从极简的概念开始,为大家揭开Animation的神秘面纱。我们以一个登录界面为例。美丽的太阳,婀娜的云,还有几个小山包,中间静躺着用户名、密码输入框和登录按钮。搁以前,这个界面许是会亮瞎眼现如今尼玛狗都嫌。所以我们的目标是赋予这个界面生命力。

注意:本文章基于Swift 2.0和Xcode 7 Beta 2编写。登录界面中的所有元素都已经连接到了代码中(outlet),在这个示例中我们先不使用Auto Layout和SizeClasses。

会动的输入框

我们的第一个场景应该是这样。用户打开App,启动画面过后显示登录界面,此时屏幕上还没有用户名和密码的输入框,下一秒他们从屏幕左侧飘然而至。

首先

我们需要在登录界面还没有展现给用户的时候把用户名和密码的输入框移至屏幕外面。打开ViewController.swift,在viewWillAppear()方法中添加以下代码:

[cpp] view plaincopy

  1. self.username.center.x -= self.view.bounds.width
  2. self.password.center.x -= self.view.bounds.width

这两行代码使用户名、密码输入框移出屏幕外,这里可以使用简单暴力的方式,直接让centerx减去屏幕宽度。

然后

我们在viewDidAppear()方法中添加以下代码:

[cpp] view plaincopy

  1. UIView.animateWithDuration(0.5, animations: {
  2. self.username.center.x += self.view.bounds.width
  3. self.password.center.x += self.view.bounds.width
  4. })

animationWithDuration(_:animations:)UIView的类方法,从方法名就可以看出,该方法可使UIView动起来。它有两个参数:

  • duration:动画的持续时间。
  • animation:动画闭包,在这个闭包中你可以改变UIView的各种动画属性。

因为该方法是一个类方法,所以在闭包中你可以同时改变多个views的动画属性。所以在上述代码中,同时改变了用户名和密码输入框的位置。编译运行,我们可以看到如下效果:

但是由于两个输入框是同时从屏幕外滑入,略显呆板,所以我们用另一个方法再来润色一下。

最后

我们更新viewDidAppear()中的代码:

[cpp] view plaincopy

  1. UIView.animateWithDuration(0.5, animations: {
  2. self.username.center.x += self.view.bounds.width
  3. //  self.password.center.x += self.view.bounds.width
  4. })
  5. UIView.animateWithDuration(0.5, delay: 0.3, options: .AllowUserInteraction, animations: {
  6. self.password.center.x += self.view.bounds.width
  7. }, completion: nil)

animationWithDuration(_:delay:options:animations:completion:)方法同样是UIView的类方法,但是多了3个参数:

  • delay:顾名思义,动画迟延执行的时间。
  • options:自定义动画的一些效果,比如重复动画、前后运动等。这个参数在后面的文章中会说明。
  • completion:也是一个闭包,当动画执行完之后会执行该闭包中的逻辑,可以用来连接动画,或者是在动画结束后你需要做一些清理工作等。

现在编译运行,可以看到如下效果:

用户名输入框先滑入屏幕,在0.3秒的延迟后,密码输入框紧随其后。

动画属性

在上一节,我们体验了视图的简单动画效果,不难发现,其实真正导致视图动起来的是animations闭包中的代码,也就是对视图属性的改变,然后UIView的类方法生成了视图某属性的起始值和终止值之间的补间动画。这引出了另一个概念,那就是视图的动画属性,诚然不是所有的视图属性都是动画属性,下面给大家介绍一下视图的动画属性。

位置和大小

  • bounds:改变视图内容的位置和尺寸大小的属性。
  • frame:改变视图的位置和尺寸大小的属性。
  • center:改变视图位置的属性。

外观

  • backgroundColor:改变背景色时,UIKit会线性的从原始颜色转变为目标颜色。
  • alpha:改变透明度,UIKit会创建淡入淡出的效果。

转换

transform属性的类型为CGAffineTransform,它是一个结构体,CoreGraphics中有若干方法可生成不同的CGAffineTransform结构,使视图旋转、按比例缩放、翻转等,我们来看看它如何使用。在viewDidAppear()方法中添加如下代码:

[cpp] view plaincopy

  1. let rotation = CGAffineTransformMakeRotation(CGFloat(M_PI))
  2. UIView.animateWithDuration(1, animations: {
  3. self.sun.transform = rotation
  4. })

首先创建了一个旋转的结构,参数是一个CGFloat类型的角度,这里我们使用预定义好的常量比如M_PI代表3.14...,也就是旋转一周、M_PI_2代表1.57...,也就是旋转半周等。

然后在animations闭包中将创建的旋转结构赋值给屏幕上太阳视图的transform属性。编译运行可以看到如下效果:

我们再来看看缩放,在viewDidAppear()方法中添加如下代码:

[cpp] view plaincopy

  1. let scale = CGAffineTransformMakeScale(0.5, 0.5)
  2. UIView.animateWithDuration(1, animations: {
  3. self.cloudBig.transform = scale
  4. })

首先创建了一个缩放的结构,第一个参数是x轴的缩放比例,第二个参数是y轴的缩放比例。同样在animations闭包中将创建的缩放结构赋值给屏幕上云朵视图的transform属性。编译运行可以看到如下效果:

动画选项

大家应该还记得我们之前使用过animationWithDuration(_:delay:options:animations:completion:)方法,其中的options当时没有详细的讲述,这节会向大家说明该属性。options选项可以使你自定义让UIKit如何创建你的动画。该属性需要一个或多个UIAnimationOptions枚举类型,让我们来看看都有哪些动画选项吧。

重复类

  • .Repeat:该属性可以使你的动画永远重复的运行。
  • .Autoreverse:该属性可以使你的动画当运行结束后按照相反的行为继续运行回去。该属性只能和.Repeat属性组合使用。

我们来看看怎么使用这两个属性,我们修改一个密码输入框的动画:

[cpp] view plaincopy

  1. UIView.animateWithDuration(0.5, delay: 0.3, options: .Repeat, animations: {
  2. self.password.center.x += self.view.bounds.width
  3. }, completion: nil)

编译运行看看效果:

可以看到密码输入框不停的从左向右滑入。大家可以自己试试.Autoreverse的效果或者[.Repeat, .Autoreverse]组合效果。

动画缓冲

在现实生活中,几乎没有什么东西可以突然开始运动,然后突然停止一动不动。可以运动的物体基本都是以较慢的速度启动,逐渐加速,达到一个稳定的速度,然后当要停止时,会逐渐减速,最后停止。所以要使动画更加逼真,也可以采用这种方式,那就是ease-inease-out

  • .CurveLinear :该属性既不会使动画加速也不会使动画减速,只是做以线性运动。
  • .CurveEaseIn:该属性使动画在开始时加速运行。
  • .CurveEaseOut:该属性使动画在结束时减速运行。
  • .CurveEaseInOut:该属性结合了上述两种情况,使动画在开始时加速,在结束时减速。

下面依然以密码输入框作为示例,修改密码输入框的动画代码:

[cpp] view plaincopy

  1. UIView.animateWithDuration(0.5, delay: 0.3, options: [.Repeat, .Autoreverse, .CurveEaseOut], animations: {
  2. self.password.center.x += self.view.bounds.width
  3. }, completion: nil)

上面的代码中组合了三种动画选项,首先让动画重复执行,然后让动画在一次执行完毕后接着反方向再次执行,最后让动画在结束时减速。编译运行,这次我们减慢动画的运行速度来看看:

从上面的效果中可以看到当密码输入框滑入屏幕的后半段时速度有明显的减慢。大家也可以在自己的项目中试试其他动画选项的组合。

结束语

看完这篇文章后,相信大家对iOS的动画有了大致的了解,也学会了如何实现简单的视图动画,当然这些只是iOS Animation的冰山一角,我会陆续向大家介绍iOS Animation的其他知识,今天就先到这吧。

作者简介:

付宇轩(@DevTalking),从事Java中间件开发、iOS开发。主要主持开发企业级ETL中间件、BPM中间件、企业级移动应用,个人博客地址:http://www.devtalking.com

时间: 2024-11-02 23:32:31

iOS UIView动画实践(一):揭开Animation的神秘面纱的相关文章

iOS UIView动画详解(Objective-C)

我在之前的一篇博客中<iOS UIView动画详解(Swift)>讲解了使用Swift来实现UIView类下面提供的多种动画效果,如位置动画.旋转动画.缩放动画.颜色动画.透明度动画等等.为了这个题目的完整性,今天我使用Objective-C来完全重写以上的所有的动画.项目案例已经上传至:https://github.com/chenyufeng1991/iOS-UIView-Animation  中的Animation-OC文件夹下,另一个目录下则是Swift实现的动画. (1)位置动画 P

揭开RecyclerView的神秘面纱(一):RecyclerView的基本使用

前言 在Android开发中,我们经常与ListView.GridView打交道,它们为数据提供了列表和视图的展示方式,方便用户的操作.然而,随着Android的不断发展,单一的listview逐渐满足不了需求多变的项目了,因此,谷歌在support v7中,加入了新的控件--RecyclerView,该控件整合了ListView.GridView的特点,而且最大的优点是可以很方便实现瀑布流效果,因此RecyclerView受到越来越多的开发者重视.所以,学习RecyclerView的使用也是很

ASP.NET 运行时详解 揭开请求过程神秘面纱

对于ASP.NET开发,排在前五的话题离不开请求生命周期.像什么Cache.身份认证.Role管理.Routing映射,微软到底在请求过程中干了哪些隐秘的事,现在是时候揭晓了.抛开乌云见晴天,接下来就一步步揭开请求管道神秘面纱. 上篇回顾 在介绍本篇内容之前,让我们先回顾下上一篇<ASP.NET运行时详解 集成模式和经典模式>的主要内容.在上一篇随笔中,我们提到ASP.NET运行时通过Application的InitInternal方法初始化运行管道.ASP.NET运行时提供了两种初始化管道模

【安全健行】(4):揭开shellcode的神秘面纱

2015/5/18 16:20:18 前面我们介绍了shellcode使用的基本策略,包括基本的shellcode.反向连接的shellcode以及查找套接字的shellcode.在宏观上了解了shellcode之后,今天我们来深入一步,看看shellcode到底是什么.也许大家和我一样,从接触安全领域就听说shellcode,也模糊地知道shellcode基本就是那个攻击载荷,但是shellcode到底长什么样,却一直遮遮掩掩,难睹真容.趁今天这个机会,我们一起来揭开shellcode的神秘面

揭开RecyclerView的神秘面纱(二):处理RecyclerView的点击事件

前言 上一篇文章揭开RecyclerView的神秘面纱(一):RecyclerView的基本使用中,主要讲述了RecyclerView的基本使用方法,不同的布局管理器而造成的多样化展示方式,展示了数据之后,一般都会与用户进行交互,因此我们需要处理用户的点击事件.在ListView和GridView提供了onItemClickListener这个监听器,然而我们查找RecyclerView的API却没有类似的监听器,因此我们需要自己手动处理它的点击事件. 以下提供两种方法来实现处理Recycler

Json系列之四 揭开JsonConfig的神秘面纱 java to json

//揭开JsonConfig的神秘面纱,for bean to json JsonConfig jsonConfig = new JsonConfig(); //忽略掉bean中含后某个注解的field,不转换成json,可以多次增加不同注解 //jsonConfig.addIgnoreFieldAnnotation(Person.class);//一定是注解的类,我这里没有例子,大家可以自己做 //同上 //jsonConfig.addIgnoreFieldAnnotation("person

SparkSQL大数据实战:揭开Join的神秘面纱

本文来自 网易云社区 . Join操作是数据库和大数据计算中的高级特性,大多数场景都需要进行复杂的Join操作,本文从原理层面介绍了SparkSQL支持的常见Join算法及其适用场景. Join背景介绍 Join是数据库查询永远绕不开的话题,传统查询SQL技术总体可以分为简单操作(过滤操作-where.排序操作-limit等),聚合操作-groupby以及Join操作等.其中Join操作是最复杂.代价最大的操作类型,也是OLAP场景中使用相对较多的操作.因此很有必要对其进行深入研究. 另外,从业

iOS UIView动画详解

现在的iOS开发中,有很多的动画框架可以使用,包括苹果自带的CoreAnimation框架,Facebook的Pop等等,这些的确都是程序员的利器.但是如果我们仅仅是想要实现一些比较简单的动画呢?杀鸡焉用牛刀.我们直接用UIView就可以了.今天我们就来好好聊聊UIView动画,使用Swift编写(大家可以看到我有时候用OC,有时候用Swift,现在的iOS学习的基本技能看着OC代码能写出Swift,照着Swift能写出OC,哈哈).本示例代码上传至  https://github.com/ch

iOS UIView动画效果 学习笔记

CGRect frame = _confirmV.frame; [UIView beginAnimations:nil context:nil];//动画定义开始 [UIView setAnimationDuration:0.5];//动画的时长 [UIView setAnimationDelay:0]; [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(removeConfirmV