介绍 EasyAnimation

原文:Introduction EasyAnimation
作者:Marin Todorov
译者:kmyhy

本教程使用 Xcode 7/Swift 2 以上版本。

//UIKit view animation
UIView.animateWithDuration(2.0,animations: {
    self.view.center.x = 200.0
})

而 CoreAnimation 不同,它需要你创建一个动画模型对象,设置它然后传递给 CoreAnimation 服务:

//CoreAnimation 图层动画
let anim = CABasicAnimation(keyPath: "position.x")
anim.fromValue = 100.0
anim.tovalue = 200.0
anim.duration = 2.0
anim.fillMode = kCAFillModeBackwards
anim.beginTime = CACurrentMediaTime() + 2.0
anim.timingFunction = camediatimingFunction(name: kcamediatimingFunctionEaSEOut)
view.layer.addAnimation(anim,forKey: nil)

EasyAnimation 能够明显减少创建图层动画的代码,扩展了 UIKit 原有的动画方法,让你将时间花在你真正想要干的事情上。

在本教程中,你将学习如何轻松地对图层属性进行动画,以及轻松地将动画串联成序列和组(我最喜欢干的)。

开始

我已经准备了一个开始项目,以节省你新建项目和创建 UI 和自动布局的工作。

下载 EAImagePreview-Starter.zip,解压缩并打开 EaimagePreview.xcodeproj。

EaimagePreview 是一个简单项目,显示一个照片列表,当点击某个 cell,显示出照片的完整大图。

打开 Main.storyboard,查看项目结构:

在 collection view 的 cell 中显示的是照片的缩略图——在 ViewController.swift 文件底部的扩展中包含了所有的 collection view 数据源方法和委托方法

你可以运行一下这个 app 看看:

点击其中某张图片,你会看到它的大图。点击大图,它又小时。开始项目是很简单的,你的任务就是使用 EasyAnimation 来增加一些亮点!

首先创建一个 Podfile 文件添加 pod EasyAnimation:

use_frameworks!
pod 'EasyAnimation'

然后安装该 pod,重新打开 Cocoapods 创建的 workspace 文件。你会在工作空间的 Pods 项目文件夹下看到 EasyAnimation 的源文件

现在来写几句代码

打开工作看见开始项目中的 ViewController.swift (它不在 Pods 项目中) 找到 showImage(image:) 方法。这个方法用于显示大图。

为了了解 EasyAnimation 能够做些什么,我们来添加几个动画。

首先是在显示大图之前,让照片列表淡出。找到并删除这句代码

self.preview.addSubview(imgView)

然后在这里开始编写代码

UIView.animateWithDuration(0.25,delay: 0.0,options: .CurveEaseIn,animations: {
    //animate collection view
    self.collectionView.transform = CGAffineTransformMakeTranslation(-30.0,0.0)
    self.collectionView.alpha = 0.5

},completion: {_ in

    //show the image view
    self.preview.addSubview(imgView)
})

在你的 app 中你肯定不止一回用到这个方法了。如果你运行这个 app,你会看到照片列表会慢慢移到一边,然后才显示出大图。

现在——如果你想在第一个动画完成时添加一个动画时怎么办?你需要在第一个动画的完成块中创建新的动画。如果你想添加第三个动画呢——需要在第二个动画的完成块中创建第三个动画,以此类推……

这种方式最终会让你的代码格式变成一场灾难,因为你的嵌套的块太深了,Xcode 不能很好地缩进你的代码块参数……

让我们来看一看 EasyAnimation 提供的解决方案。EasyAnimation 在 UIView 类上添加一个新的方法,允许你轻松地将链式动画串在一起:

找到 ViewController.swift 头部,导入 EasyAnimation:

import EasyAnimation

回到 showImage(image:) 方法,将 animateWithDuration 替换成 animateAndChainWithDuration。chain 方法的参数和原来的方法参数是一样的,所以你只要修改方法名即可:

UIView.animateAndChainWithDuration(0.25,options: .CurveEaseIn,animations: {
   //animate collection view
   ...

如果你运行 app,你会发现结果没有什么不同。

但是,如果回到代码中将方法调用最后的 ] 符号后面加一个 “.”,你会发现你可以以链式调用新的动画方法。比如:

我真的想说:这也太“贴心”了吧 :)

假设要在你的动画序列中添加一个弹簧动画——你的动画代码将变成:

UIView.animateAndChainWithDuration(0.25,completion: {_ in

    //show the image view
    self.preview.addSubview(imgView)
}).animateWithDuration(2.0,usingSpringWithdamping: 0.25,initialSpringVeLocity: 0.0,options: [],animations: {

    //second animation here

},completion: nil)

这段代码将先执行第一个动画,然后然后执行完成块中的代码,然后执行新加入的第二个动画。
在 // second animation here (在第二个动画块中)编写:

self.collectionView.transform = CGAffineTransformMakeTranslation(-100.0,0.0)

第二个动画只是将 collection 向左边再移动一些。如果你运行 app,你会看到列表会出现一个反弹效果。这两个动画的拼接是完全无缝的,因为 EasyAnimation 在内部使用完成块将他们串起来了。

接下来试一下 EasyAnimation 的另一个功能。来点图层动画增加点味道怎么样?

在最后一句后面加入:

imgView.layer.borderWidth = 5.0

啊——使用 EasyAnimation 之后就是这样简单。不需要创建 CABasicAnimation 对象之类的小编,你可以用像对 UIView 属性进行动画的方式来对 CALayer 属性进行动画。

运行 app,你会看到当大图显示后会开始一个小小的边框动画。注意边框也会动——它也是弹簧动画!

实际上,UIKit 自己也会处理一些 CALayer 动画。例如,如果你进行一个 CALayer 变换,UIKit 会自动处理这个动画。最大的好处是,你无需关心哪些动画是 UIKit 来负责,哪些是 EasyAnimation 来负责,因为现在它们都是一样的了。继续添加代码

var imgFlip = CATransform3DIdentity
imgFlip.m34 = -1.0 / 1000
imgFlip = CATransform3DRotate(imgFlip,CGFloat(-M_PI_4),0.0,1.0,0.0)
imgFlip = CATransform3DTranslate(imgFlip,100.0,0.0)

imgView.layer.transform = imgFlip

注意:如果你不太清楚其中 3D 变换的代码,请参考 iOS Animations by Tutorials 中的第四部分“3D 动画”。

现在的动画更有趣了:

你还需要再添加一个动画到序列中,在大图的周围显示一个漂亮的光晕,才是我们最终的效果

向上滚动代码,在调用 UIView.animateAndChainWithDuration 一句之前插入代码

imgView.layer.shadowColor = UIColor.whiteColor().CGColor
    imgView.layer.shadowOffset = CGSize(width: 0,height: 0)
    imgView.layer.shadowOpacity = 0.9

这段代码会在 image view 上加上一个光晕(实际上它不过是一个白色阴影,只不过看起来就像白色光晕而已)。然后在动画序列中添加一个新的动画,对这个光晕执行动画:

imgView.layer.transform = imgFlip

},completion: nil).animateWithDuration(2.0,delay: 0.25,animations: {
    //increase the shadow radius (by default it's 3.0)
    imgView.layer.shadowRadius = 30.0
},completion: nil)

运行 app,欣赏一下完整的动画序列效果

如果你想再进一步完善动画效果,你可以找到 closeImage(tap:) 方法,将整个方法包装在一个动画调用中。现在关闭大图的效果变得更好看了。

在这篇短教程里,你学习了如何:

  • 将动画串在一起
  • 将 UIView 动画和 CALayer 动画放在同一个动画调用
  • 对 CALayer 属性进行弹簧动画
  • 将 UIKit 和 EasyAnimate 动画同等对待

如果你想了解更多 EasyAnimation 的例子,请从 GitHub 上克隆并运行它的示例 app: https://github.com/icanzilb/EasyAnimation.

要是你不喜欢出血效果,请参考 dev-marin 分支: https://github.com/icanzilb/EasyAnimation/tree/dev-marin.

接下来做什么?

重新阅读 iOS Animations by Turtorials 第三部分“图层动画”吧——这会让你更好地知道如何用 EasyAnimation 去重构你的 CALayer 动画,让代码更简洁。

如果你准备基于本教程的内容编写一些好玩的小编,请回复这封邮件或者 twitter 给我 @icanzilb。

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...