如何为 UIView 关键帧动画设置动画曲线(`func UIView.animateKeyframes()`)
Posted
技术标签:
【中文标题】如何为 UIView 关键帧动画设置动画曲线(`func UIView.animateKeyframes()`)【英文标题】:How do I set animation curves for UIView keyframe animations (`func UIView.animateKeyframes()`) 【发布时间】:2021-06-20 13:52:26 【问题描述】:UIView 关键帧动画让您可以创建通过一系列步骤进行的视图动画。函数animateKeyframes(withDuration:delay:options:animations:completion:)
有一个UIView.KeyframeAnimationOptions
类型的选项参数。我希望这能让我选择一个整体时序曲线以应用于组合的动画集。它似乎应用了缓入缓出的默认动画曲线,并且似乎不允许您像UIView.animate()
系列方法那样指定时序曲线。如果我想要线性时序,只是缓入或缓出怎么办?
【问题讨论】:
【参考方案1】:有趣的是,UIView.animate()
方法(UIView.AnimationOptions
类型)的动画选项如果你能弄清楚如何将它们传递给 animateKeyframes(withDuration:delay:options:animations:completion:)
就可以工作。不幸的是,没有现有的时间曲线常数,如线性、缓入或缓出。 This SO answer 展示了如何将值从 UIView.AnimationOptions
常量“强制”到 UIView.KeyframeAnimationOptions
OptionSet:
extension UIViewKeyframeAnimationOptions
init(animationOptions: UIViewAnimationOptions)
rawValue = animationOptions.rawValue
我更进一步,为不同的计时函数定义了常数。 (我不知道为什么苹果没有定义这些。这看起来很荒谬,但你就是这样。)
我对@987654331@ 的扩展如下所示:
extension UIView.KeyframeAnimationOptions
static var curveLinear: UIView.KeyframeAnimationOptions =
UIView.KeyframeAnimationOptions(rawValue:UIView.AnimationOptions.curveLinear.rawValue)
static var curveEaseInOut: UIView.KeyframeAnimationOptions =
UIView.KeyframeAnimationOptions(rawValue:UIView.AnimationOptions.curveEaseInOut.rawValue)
static var curveEaseIn: UIView.KeyframeAnimationOptions =
UIView.KeyframeAnimationOptions(rawValue:UIView.AnimationOptions.curveEaseIn.rawValue)
static var curveEaseOut: UIView.KeyframeAnimationOptions =
UIView.KeyframeAnimationOptions(rawValue:UIView.AnimationOptions.curveEaseOut.rawValue)
init(animationOptions: UIView.AnimationOptions)
self.init(rawValue: animationOptions.rawValue)
使用该扩展,您可以像调用 UIView.animate()
方法一样使用时序曲线值:
UIView.animateKeyframes(withDuration: 2.0, delay: 0, options: [.curveLinear])
// Your animation keyframe steps here
在 UIView.AnimationOptions 中定义的其他一些标志也可能对UIView.KeyframeAnimationOptions
有效。您可以使用将UIView.AnimationOptions
映射到UIView.KeyframeAnimationOptions
的方法,或者像我添加时序曲线标志一样向UIView.KeyframeAnimationOptions
添加额外的标志。
编辑:
我很好奇 UIView.animate()
和 animateKeyframes()
选项中的标志是否匹配。我编写了一些代码来记录两个选项集的所有值,这就是我得到的:
KeyframeAnimationOptions:
option value 0x00000001 = layoutSubviews
option value 0x00000002 = allowUserInteraction
option value 0x00000004 = beginFromCurrentState
option value 0x00000008 = repeat
option value 0x00000010 = autoreverse
option value 0x00000020 = overrideInheritedDuration
option value 0x00000200 = overrideInheritedOptions
option value 0x00000000 = calculationModeLinear
option value 0x00000400 = calculationModeDiscrete
option value 0x00000800 = calculationModePaced
option value 0x00000C00 = calculationModeCubic
option value 0x00001000 = calculationModeCubicPaced
UIView.AnimationOptions:
option value 0x00000001 = layoutSubviews
option value 0x00000002 = allowUserInteraction
option value 0x00000004 = beginFromCurrentState
option value 0x00000008 = repeat
option value 0x00000010 = autoreverse
option value 0x00000020 = overrideInheritedDuration
option value 0x00000200 = overrideInheritedOptions
option value 0x00000040 = overrideInheritedCurve
option value 0x00000080 = allowAnimatedContent
option value 0x00000100 = showHideTransitionViews
option value 0x00000000 = curveEaseInOut
option value 0x00010000 = curveEaseIn
option value 0x00020000 = curveEaseOut
option value 0x00030000 = curveLinear
option value 0x00100000 = transitionFlipFromLeft
option value 0x00200000 = transitionFlipFromRight
option value 0x00300000 = transitionCurlUp
option value 0x00400000 = transitionCurlDown
option value 0x00500000 = transitionCrossDissolve
option value 0x00600000 = transitionFlipFromTop
option value 0x00700000 = transitionFlipFromBottom
option value 0x03000000 = preferredFramesPerSecond60
option value 0x07000000 = preferredFramesPerSecond30
两组中的前 7 个标志具有相同的名称和相同的值。 KeyframeAnimationOptions
的 0 值为 calculationModeLinear
,而 UIView.AnimationOptions 的值为 curveEaseInOut
。它会导致关键帧和“常规”UIView 动画的缓入/缓出计时。
所有其他常量的值在两个选项集中都是唯一的,这表明其他一些 UIView.AnimationOptions
可能适用于关键帧动画。不过,我只测试了时序曲线值,它们都按预期工作。
编辑#2:
关键帧动画标志(如calculationModeLinear、calculationModeCubic和calculationModeCubicPaced)和视图动画标志(如curveLinear、curveEaseInOut等)如何交互并不是很明显,因为关键帧动画标志也与动画时间有关.我写了一个测试应用程序来看看他们是怎么做的。事实证明,UIView.AnimationOptions 时序曲线标志会影响整个关键帧动画的整体时序。 (整个关键帧动画开始和停止的方式。)
您可以从 githubhere 下载示例项目。
很难看到缓入/缓出 UIView 动画时间与立方关键帧动画选项之一相结合。使用关键帧计算模式线性模式更容易看到缓入/缓出。
以下是该组合的视频:
(请注意青色正方形在返回到起点之前如何在动画矩形的右下角停止。)
【讨论】:
以上是关于如何为 UIView 关键帧动画设置动画曲线(`func UIView.animateKeyframes()`)的主要内容,如果未能解决你的问题,请参考以下文章
如何为嵌入在 UITableViewCell 中的 UIView 设置动画
如何为 UICollectionViewCell 的帧更改设置动画