前言
在一个看脸的社会中,不论什么事物,长得好看总是能多吸引一些目光。App同样不例外,一款面相不错的App就算功能已经被轮子千百遍,依然会有人买账,理由就是看得顺眼,于是平面设计人员越来越被重视。白驹过隙,斗转星移,人们已然不满足于静态的美感,于是动态的用户体验应运而生,平面设计人员捉襟见肘,是我们程序员出马的时候了。
这篇文章是UIView Animation的第一篇,从极简的概念开始,为大家揭开Animation的神秘面纱。我们以一个登录界面为例。美丽的太阳,婀娜的云,还有几个小山包,中间静躺着用户名、密码输入框和登录按钮。搁以前,这个界面许是会亮瞎眼现如今尼玛狗都嫌。所以我们的目标是赋予这个界面生命力。
注意:本文章基于Swift 2.0和Xcode 7 Beta 2编写。登录界面中的所有元素都已经连接到了代码中(outlet),在这个示例中我们先不使用Auto Layout和SizeClasses。
会动的输入框
我们的第一个场景应该是这样。用户打开App,启动画面过后显示登录界面,此时屏幕上还没有用户名和密码的输入框,下一秒他们从屏幕左侧飘然而至。
首先
我们需要在登录界面还没有展现给用户的时候把用户名和密码的输入框移至屏幕外面。打开ViewController.swift
,在viewWillAppear()
方法中添加以下代码:
- self.username.center.x -= self.view.bounds.width
- self.password.center.x -= self.view.bounds.width
这两行代码使用户名、密码输入框移出屏幕外,这里可以使用简单暴力的方式,直接让center
的x
减去屏幕宽度。
然后
我们在viewDidAppear()
方法中添加以下代码:
- UIView.animateWithDuration(0.5, animations: {
- self.username.center.x += self.view.bounds.width
- self.password.center.x += self.view.bounds.width
- })
animationWithDuration(_:animations:)
是UIView
的类方法,从方法名就可以看出,该方法可使UIView
动起来。它有两个参数:
duration
:动画的持续时间。animation
:动画闭包,在这个闭包中你可以改变UIView
的各种动画属性。
因为该方法是一个类方法,所以在闭包中你可以同时改变多个views
的动画属性。所以在上述代码中,同时改变了用户名和密码输入框的位置。编译运行,我们可以看到如下效果:
但是由于两个输入框是同时从屏幕外滑入,略显呆板,所以我们用另一个方法再来润色一下。
最后
我们更新viewDidAppear()
中的代码:
- UIView.animateWithDuration(0.5, animations: {
- self.username.center.x += self.view.bounds.width
- // self.password.center.x += self.view.bounds.width
- })
- UIView.animateWithDuration(0.5, delay: 0.3, options: .AllowUserInteraction, animations: {
- self.password.center.x += self.view.bounds.width
- }, 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()
方法中添加如下代码:
- let rotation = CGAffineTransformMakeRotation(CGFloat(M_PI))
- UIView.animateWithDuration(1, animations: {
- self.sun.transform = rotation
- })
首先创建了一个旋转的结构,参数是一个CGFloat
类型的角度,这里我们使用预定义好的常量比如M_PI
代表3.14...,也就是旋转一周、M_PI_2
代表1.57...,也就是旋转半周等。
然后在animations
闭包中将创建的旋转结构赋值给屏幕上太阳视图的transform
属性。编译运行可以看到如下效果:
我们再来看看缩放,在viewDidAppear()
方法中添加如下代码:
- let scale = CGAffineTransformMakeScale(0.5, 0.5)
- UIView.animateWithDuration(1, animations: {
- self.cloudBig.transform = scale
- })
首先创建了一个缩放的结构,第一个参数是x轴的缩放比例,第二个参数是y轴的缩放比例。同样在animations
闭包中将创建的缩放结构赋值给屏幕上云朵视图的transform
属性。编译运行可以看到如下效果:
动画选项
大家应该还记得我们之前使用过animationWithDuration(_:delay:options:animations:completion:)
方法,其中的options
当时没有详细的讲述,这节会向大家说明该属性。options
选项可以使你自定义让UIKit
如何创建你的动画。该属性需要一个或多个UIAnimationOptions
枚举类型,让我们来看看都有哪些动画选项吧。
重复类
.Repeat
:该属性可以使你的动画永远重复的运行。.Autoreverse
:该属性可以使你的动画当运行结束后按照相反的行为继续运行回去。该属性只能和.Repeat
属性组合使用。
我们来看看怎么使用这两个属性,我们修改一个密码输入框的动画:
- UIView.animateWithDuration(0.5, delay: 0.3, options: .Repeat, animations: {
- self.password.center.x += self.view.bounds.width
- }, completion: nil)
编译运行看看效果:
可以看到密码输入框不停的从左向右滑入。大家可以自己试试.Autoreverse
的效果或者[.Repeat, .Autoreverse]
组合效果。
动画缓冲
在现实生活中,几乎没有什么东西可以突然开始运动,然后突然停止一动不动。可以运动的物体基本都是以较慢的速度启动,逐渐加速,达到一个稳定的速度,然后当要停止时,会逐渐减速,最后停止。所以要使动画更加逼真,也可以采用这种方式,那就是ease-in和ease-out。
.CurveLinear
:该属性既不会使动画加速也不会使动画减速,只是做以线性运动。.CurveEaseIn
:该属性使动画在开始时加速运行。.CurveEaseOut
:该属性使动画在结束时减速运行。.CurveEaseInOut
:该属性结合了上述两种情况,使动画在开始时加速,在结束时减速。
下面依然以密码输入框作为示例,修改密码输入框的动画代码:
- UIView.animateWithDuration(0.5, delay: 0.3, options: [.Repeat, .Autoreverse, .CurveEaseOut], animations: {
- self.password.center.x += self.view.bounds.width
- }, completion: nil)
上面的代码中组合了三种动画选项,首先让动画重复执行,然后让动画在一次执行完毕后接着反方向再次执行,最后让动画在结束时减速。编译运行,这次我们减慢动画的运行速度来看看:
从上面的效果中可以看到当密码输入框滑入屏幕的后半段时速度有明显的减慢。大家也可以在自己的项目中试试其他动画选项的组合。
结束语
看完这篇文章后,相信大家对iOS的动画有了大致的了解,也学会了如何实现简单的视图动画,当然这些只是iOS Animation的冰山一角,我会陆续向大家介绍iOS Animation的其他知识,今天就先到这吧。
作者简介:
付宇轩(@DevTalking),从事Java中间件开发、iOS开发。主要主持开发企业级ETL中间件、BPM中间件、企业级移动应用,个人博客地址:http://www.devtalking.com。