有趣的是,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 动画时间与立方关键帧动画选项之一相结合。使用关键帧计算模式线性模式更容易看到缓入/缓出。
以下是该组合的视频:
(请注意青色正方形在返回到起点之前如何在动画矩形的右下角停止。)