本文旨在成为iOS动画的入门,目的是详尽介绍各种不同的实现方式。
鉴于该主题的广泛性,我们将在相当高的层次上简要介绍每个部分。目的是教育读者一系列选择,以将动画添加到他/她的iOS应用程序中。
在开始与iOS相关的主题之前,让我们简要看一下动画速度。
以60FPS动画
通常,在视频中,每个帧都由一幅图像表示,并且帧速率决定了序列中翻转的图像数量。这称为“每秒帧数”或FPS。
FPS确定在一秒钟内翻转的静止图像的数量,这从字面上意味着图像/帧的数量越多,视频中显示的细节/信息越多。动画也是如此。
FPS通常用于确定动画的质量。普遍认为,任何好的动画都应以60fps或更高的速度运行-低于60fps的任何动画都会让人感觉有些不适。
您要查看30FPS和60FPS之间的区别吗?检查一下!
您注意到差异了吗?人眼绝对可以感觉到较低fps的抖动。因此,始终要确保您创建的任何动画都遵循以60FPS或更高的速度运行的基本规则,这始终是一个好习惯。这使它感觉更加逼真和生动。
看完FPS之后,让我们深入研究不同的iOS核心框架,这些框架为我们提供了一种执行动画的方法。
核心框架
在本节中,我们将介绍可用于创建视图动画的iOS SDK中的框架。我们将快速浏览它们中的每一个,并通过相关示例解释它们的功能集。
UIKIT / UIVIEW动画
UIView是在iOS应用程序中显示内容的任何视图的基类。
提供给我们UIView的框架UIKit已经为我们提供了一些基本的动画功能,这些功能使开发人员可以轻松完成更多任务。
API UIView.animate
是最简单的动画视图方法,因为通过以基于块的语法提供属性值,可以轻松地对任何视图的属性进行动画处理。
在UIKit动画中,建议仅修改UIVI的可设置动画的属性,否则会产生一些影响,在这些动画中,动画可能导致视图最终以意外状态结束。
动画(withDuration:动画:完成)
此方法需要动画时间,需要对一组视图的可动画属性更改进行动画处理。当完成执行动画的视图时,完成块将提供回调。
使用此单一API几乎可以实现视图上任何类型的动画,例如在视图上移动,缩放,旋转,淡化等。
现在,考虑要对按钮大小进行动画处理,或者要使特定视图放大到屏幕中。这是我们使用UIView.animate
API的方法:
这是我们在这里做的事情:
- 我们
UIView.animate
使用传递给它的持续时间值调用该方法,该持续时间值表示该块内描述的动画应运行多长时间。 - 我们设置按钮的新框架,该框架应代表动画的最终状态。
- 我们将按钮设置
center
为其超级视图的中心,以使其保持在屏幕中心。
上面的动画代码块应触发按钮的帧从当前帧改变的动画:
Width = 0, Height = 0
到最后一帧:
Width = Height = newButtonWidth
这是动画的样子:
animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion
此方法类似于animate方法的扩展,在其中您可以执行在现有API中可以执行的所有操作,并且可以将一些物理行为添加到视图动画中。
例如,如果您想在上面完成的动画中实现弹簧阻尼效果,那么代码就是这样的:
这是我们使用的参数集:
duration
表示确定代码块应运行多长时间的动画持续时间。delay
表示在动画开始之前我们想要的初始延迟。SpringWithDamping
表示我们希望视图表现的弹性效果的值。该值必须在0到1之间。该值越小,弹簧振荡越高。velocity
表示动画开始的速度。options
要应用于视图动画的动画曲线的类型。- 最后,是我们设置需要动画的按钮框架的代码块。与上一个动画相同。
这是上面的动画配置的动画外观:
UIViewPropertyAnimator
要对动画进行更多控制,UIViewPropertyAnimator
可以使用它为我们提供一种暂停和恢复动画的方式。您可以自定义时间,并使动画具有交互性和可中断性。当执行还可以与用户动作交互的动画时,这非常有用。
经典的“滑动解锁”手势和播放器视图关闭/扩展动画(在“音乐”应用中)是交互式和可中断动画的示例。您可以开始用手指移动视图,然后松开它,视图将返回其原始位置。或者,您可以在动画期间捕捉视图,然后继续用手指拖动它。
以下是一个简单的示例,说明如何使用来实现动画UIViewPropertyAnimator
:
这是我们正在做的:
- 我们
UIViewProperty
通过传递持续时间和动画曲线来调用API。 - 与上述两个UIView.animate API不同,除非您自行指定动画,否则动画将不会开始,即您完全控制了完整的动画过程/流程。
现在,假设您希望对动画进行更多控制。例如,您要设计和控制动画中的每个帧。还有另一种API animateKeyframes
。但是在深入研究之前,让我们快速看一下动画中的帧是什么。
什么是A frame
?
从开始状态到最终状态的视图帧更改/过渡的集合定义为animation
,动画期间视图的每个位置称为frame
。
动画关键帧
该API提供了一种设计动画的方式,您可以用不同的时间和过渡定义多个动画。发布此消息后,API会将所有动画简单地集成到一个无缝的体验中。
假设我们要以随机方式在屏幕上移动按钮。让我们看看如何使用关键帧动画API来这样做。
这是细分:
duration
通过传入动画的持续时间来调用API。delay
动画的初始延迟时间。options
要应用于视图动画的动画曲线的类型。animations
包含开发人员/用户设计的所有关键帧动画的块。addKeyFrame
调用API设计每个动画。在我们的例子中,我们定义了按钮的每个动作。我们可以根据需要将任意数量的动画添加到块中。relativeStartTime
在动画块的集合中定义动画的开始时间。relativeDuration
定义此特定动画的总体持续时间。center
在我们的例子中,我们只需更改按钮的center属性即可在屏幕上移动按钮。
这就是最终动画的样子:
核心动画
任何基于UIKit的动画都会在内部转换为核心动画。因此,核心动画框架充当任何UIKit动画的支持层或主干。因此,所有UIKit动画API都不过是核心动画API的封装层(以易于消耗或方便的方式)。
UIKit动画API不能很好地控制已在视图上执行的动画,因为它们主要用于视图的可设置动画的属性。因此,在这种情况下,如果您打算控制动画的每一帧,最好直接使用底层的核心动画API。另外,UIView动画和核心动画也可以结合使用。
UIView +核心动画
让我们看看如何使用UIView和Core Animation API重新创建相同的按钮更改动画以及指定时序曲线。
我们可以使用CATransaction
的计时功能,该功能可让您指定和控制动画曲线。
让我们来看一个使用CATransaction
的计时功能和UIView动画组合的按钮大小更改动画的示例,其角角半径为:
这是细分:
begin
表示动画代码块的开始。duration
动画总时长。curve
表示需要应用于动画的时序曲线。UIView.animate
我们的第一个动画,用于更改按钮的框架。CABasicAnimation
我们CABasicAnimation
通过cornerRadius
将按钮的用作键路径来创建对象,因为这就是我们要设置动画的对象。同样,如果您希望对关键帧动画进行精细级别的控制,则可以使用CAKeyframeAnimation
该类。fromValue
表示动画的起始值,即cornerRadius
动画必须从其开始的按钮的初始值。toValue
表示动画的最终cornerRadius
值,即动画必须结束的按钮的最终值。cornerRadius
我们必须将cornerRadius
按钮的属性设置为动画的最终值,否则动画完成后,按钮的cornerRadius值将自动恢复为其初始值。addAnimation
通过表示需要对其执行动画的Keypath,将包含整个动画过程的配置的动画对象附加到该图层。commit
表示动画代码块的结尾,并从动画开始。
这是最终动画的样子:
该博客非常有用,可以帮助您创建更高级的动画,它巧妙地引导您完成大多数Core Animation框架API的指导,并指导您逐步进行操作。
UIKITDYNAMICS
UIKit Dynamics是UIKit的物理引擎,使您可以向UIKit控件添加任何物理行为,例如碰撞,重力,推动,捕捉等。
UIKitDynamicAnimator
这是UIKit Dynamics框架的admin类,用于管理由任何给定的UI控件触发的所有动画。
UIKitDynamicBehavior
它使您可以将任何物理行为添加到动画师,然后使其能够在附加到它的视图上执行。
UIKitDynamics的不同类型的行为包括:
UIAttachmentBehavior
UICollisionBehavior
UIFieldBehavior
UIGravityBehavior
UIPushBehavior
UISnapBehavior
UIKitDynamics的体系结构看起来像这样。请注意,项目1至5可以用单个视图替换。
让我们对按钮应用一些物理行为。我们将看到如何在按钮上施加重力,从而使我们有一种处理真实物体的感觉。
这是细分:
UIKitDynamicAnimator
我们创建了一个UIKitDynamicAnimator
对象,用作执行动画的协调器。我们还通过了按钮的超级视图作为参考视图。UIGravityBehavior
我们已经创建了一个UIGravityBehavior
对象,并将按钮传递到注入该行为的数组元素中。addBehavior
我们已将重力对象添加到动画师。这将创建一个动画,如下所示:
我们应该告诉动画师将屏幕的底部视为地面。这就是
UICollisionBehavior
图片。UICollisionBehavior
我们创建了一个UICollisionBehavior
对象并沿按钮传递,以便将行为添加到元素中。translatesReferenceBoundsIntoBoundary
启用此属性将通知动画制作者将参考视图边界作为终点,在本例中为屏幕的底部。addBehavior
我们在此处向动画师添加了碰撞行为。现在,我们的按钮应该落地并静止不动,如下所示:
那很整洁,不是吗?
现在,让我们尝试添加一个弹跳效果,使我们的物体更真实。为此,我们将使用
UIDynamicItemBehavior
该类。UIDynamicItemBehavior
我们已经创建了一个UIDynamicItemBehavior
对象并传递按钮,以便将行为添加到元素中。elasticity
值必须在0-1之间,它表示弹性,即物体在被击中时必须在地面上弹起或从地面弹起的次数。这就是魔术发生的地方-通过调整此属性,您可以区分不同种类的对象,例如球,瓶子,硬物等。addBehavior
我们在此处向动画师添加了碰撞行为。
现在,当按钮撞到地面时,它应该会弹起,如下所示:
此存储库非常有用,它显示了所有正在运行的UIKitDynamics行为。它还提供了处理每种行为的源代码。我认为,这应该是在视图上执行iOS动画的方式的广泛清单!
在下一部分中,我们将简要介绍可帮助我们测量动画性能的工具。我还建议您考虑优化Xcode构建的方法,因为它可以节省大量的开发时间。
性能调优
在本节中,我们将探讨测量和调整iOS动画性能的方法。作为iOS开发人员,您可能已经使用Xcode工具(例如“内存泄漏”和“分配”)来衡量整个应用程序的性能。同样,有些工具可用于衡量动画的效果。
Core Animation
仪器
尝试使用该Core Animation
仪器,您应该能够看到应用程序屏幕提供的FPS。这是一种衡量iOS应用中渲染的动画的性能/速度的好方法。
画画
应用程序中的FPS大大降低了,该应用程序显示大量内容(例如图像)和效果(例如阴影)。在这种情况下,请UIImageView
尝试使用Core Graphics API在上下文中单独绘制图像,而不是直接将Image分配给的image属性。通过在单独的线程而不是主线程中异步执行图像解压缩逻辑,可以过度减少图像显示时间。
栅格化
栅格化是一种用于缓存复杂层信息的过程,以便这些视图在渲染时不会被重绘。重绘视图是降低FPS的主要原因,因此,最好对将要重复使用几次的视图应用栅格化。
包起来
最后,我还总结了一些有关iOS动画的有用资源。在处理iOS动画时,您可能会发现这非常方便。此外,在深入研究动画之前,这组设计工具还可以作为(设计)步骤有用。
我希望我能够涵盖有关iOS动画的尽可能多的主题。如果我可能在本文中错过了任何内容,请在下面的评论部分中告诉我,我很乐意添加!