这是我参与「第四届青训营」笔记创作活动的的第十八天。本篇文章将会翻译一篇讲解UIView动画的文章。原文链接:medium.com/doyeona/ani… (作者:Doyeona)
动画可以增加视觉线索,通知用户应用程序中正在发生的事情。在iOS中,动画被广泛用于重新定位视图、改变其大小、将其从视图层次中移除,以及隐藏它们。你可能会使用动画来向用户传达反馈信息或实现有趣的视觉效果。 --developer.apple
在iOS中,我们不需要写任何绘图代码,因为苹果为我们提供了它。我们只需要做的是触发动画,让Core animation处理单个帧的渲染。
3种类型的动画
- UIKit
- 核心动画
- UIViewPropertyAnimator
什么时候使用,使用什么?
最后,所有UIKit风格的动画都被转换为Core Animation风格的动画。也就是说,所有的东西实际上都是用Core Animation来做动画的。--StackOverFlow
UIKit:动画是使用UIView对象进行的。视图支持一套基本的动画,涵盖许多常见的任务,如视图转换。它可以接受来自用户的事件,如触摸、点击和敲击,它在主线程中工作。
核心动画:在为底层属性制作动画时使用核心动画。它渲染、合成和动画视觉元素,提供高帧率和平滑的动画,而不会给CPU带来负担和拖慢应用程序。
UIViewPropertyAnimator:允许UIView属性的复杂和动态动画。
还在为使用什么而困惑吗?下面的图片将帮助你弄清楚!
图一:
图二:
- 框架:修改这个属性来改变视图的大小和相对于父视图坐标的位置系统(如果transform属性不包含恒等转换就修改为bounds/center属性。)
- 界限:修改此属性以改变视图的大小。
- 中心:修改此属性以改变相对于父视图的坐标系的位置。
- 转换:修改此属性以相对于其他中心点缩放、平移、旋转视图,此属性总是在2D空间中执行(如果要执行3D转换就必须要使用核心动画动画视图的层对象。)
- alpha:修改此属性以逐渐改变视图的透明度。
- 背景颜色:修改此属性来改变背景的颜色。
- 内容拉伸:修改此属性以改变视图内容的拉伸方式以填充可用的空间。
如果你的视图承载了自定义图层对象--也就是没有关联视图的对象--你必须使用Core Animation来对它们的任何变化制作动画。
UIView的动画
使用UIKit,是实现你的代码的最简单的方法! 非常直接的API,可以作为一个初学者使用。
iOS上的所有动画都是使用Core Animation运行的。UIKit的基于块的动画方法只是一个方便的功能 虽然UIKit和Core Animation都提供了动画支持,但它们对视图层次结构的不同部分给予了访问。
class func animate(withDuration duration: TimeInterval,
delay: TimeInterval,
options: UIView.AnimationOptions = [],
animations: @escaping () -> Void,
completion: ((Bool) -> Void)? = nil)
duration 动画的总持续时间。
delay 在开始动画之前要等待的时间(秒)。
options 关闭的选项,表示你要如何执行动画 .autoreverse .repeater .curveEaseOut .curveEaseIn,点击查看更容:developer.apple.com/documentati…
对于过渡,选项以trans开头,例如:.transitionCrossDissolve
animations 一个块对象{},包含要提交给视图的变化。
completion 一个在动画序列结束时要执行的块对象。
让我们来编码吧! 那么如何用视图制作简单的动画呢?我在故事板中创建了一个标签和视图,并将它们连接到ViewController中。任务是:
1️. 改变视图的背景颜色
2️. 改变视图的高度和宽度的宽度
当你运行代码时,视图的背景颜色会变成粉红色,视图的大小也会变大。但如果你想在这些动画之后马上做另一个动画怎么办?我喜欢改变视图的位置和视图的颜色。
我们可以使用一个完成处理程序,在动画之后马上给出另一个动画。
动画效果图可以点击此链接查看原图miro.medium.com/max/1348/1*… )
在动画过程中,触摸事件变得不可用,所以要使它能够使用,你必须使allowUserInteraction = true。
好了!你知道它是如何工作的了吧? 试着改变数字和选项来适应它。另外,你有没有注意到还有一个使用SpringWithDamping的方法?
它使用对应于物理弹簧运动的定时曲线来执行视图动画。
这些是增加的参数。
dampingRatio为了使动画平滑减速而不产生振荡(以常规速度来回运动),使用1的值。
velocity 弹簧的初始速度。值为1对应于一秒钟内穿越的总动画距离。(当它接近0时变得更快)
查看动画效果图点击此链接:miro.medium.com/max/1348/1*…
我做了一个有点奇怪的动画,上面使用了.repeat, .autoreverse选项,所以这就是使用usingSpringWithDamping时的动画效果,你可以在一个数组中使用多个选项。
等等......如果我有多个代码块(像下面的代码那样的嵌套块)怎么办? 有什么办法可以改进代码吗?
@IBAction func animateBtnDidtouch(_ sender: Any) {
UIView.animate(withDuration: 1, animations: {
self.simpleView.backgroundColor = .brown
}){ _ in
UIView.animate(withDuration: 1, delay: 0.25, options: [.autoreverse, .repeat], animations: {
self.simpleView.frame.origin.y -= 20
}){ _ in
UIView.animate(withDuration: 1) {
//code
}
}
}
}
animateKeyframes
这就是为什么我们用keyframe来改善那些讨厌的代码块,只是在一个! AnimateKeyframe创建一个动画块对象,可以用来为当前视图设置基于关键帧的动画。
class func animateKeyframes(withDuration duration: TimeInterval,
delay: TimeInterval,
options: UIView.KeyframeAnimationOptions = [],
animations: @escaping () -> Void,
completion: ((Bool) -> Void)? = nil)
animations 一个包含要提交给视图的变化的块对象。通常,你调用addkeyframe(withRelativeStartTime:relativeDuration:animations:)方法。
addKeyframe:指定一个关键帧动画的单帧的时间和动画值。
frameStartTime: 开始指定动画的时间。这个值必须在0到1的范围内。
frameDuration:为指定值制作动画的时间长度。这个值必须在0到1的范围内,表示相对于整个动画长度的时间量。
animations: 一个包含你要执行的动画的块对象。这个参数不能为零。
@IBAction func animateBtnDidTouch(_ sender: Any) {
UIView.animateKeyframes(withDuration: 4, delay: 0, animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.25, animations: {
self.animationView.backgroundColor = .magenta
})
UIView.addKeyframe(withRelativeStartTime: 0.25, relativeDuration: 0.25, animations: {
self.animationView.alpha = 0.5
})
UIView.addKeyframe(withRelativeStartTime: 0.50, relativeDuration: 0.25, animations: {
self.animationView.center.x = self.view.bounds.width - 100
})
UIView.addKeyframe(withRelativeStartTime: 0.75, relativeDuration: 0.25, animations: {
self.animationView.center.x = self.view.bounds.width - 200
})
})
}
}
最终得到的动画效果图片地址:miro.medium.com/max/1348/1*…
UIView.animateKeyframe(withDuration: 4, ....)意味着动画的总时长将是4秒
withRelativeStartTime是动画的开始时间。
relativeDuration是动画呈现的时间。如果它是0.25,那么它意味着4的四分之一,相当于1(秒)。
因此,每个addKeyframe将呈现一秒,而动画的总时长将是4秒。
动画工作:
- 将背景颜色改为.magenda
- 将alpha设为0.5
- 改变X的中心