如何为 UIView 关键帧动画设置动画曲线 (`func UIView.animateKeyframes()`)

如何解决如何为 UIView 关键帧动画设置动画曲线 (`func UIView.animateKeyframes()`)

UIView 关键帧动画可让您创建通过一系列步骤进行的视图动画。函数 animateKeyframes(withDuration:delay:options:animations:completion:)一个 UIView.KeyframeAnimationoptions 类型的选项参数。我希望这能让我选择一个整体时间曲线来应用于组合的动画集。它似乎应用了缓入、缓出的认动画曲线,并且似乎不允许您像 UIView.animate() 方法系列那样指定时序曲线。如果我想要线性时序、缓入或缓出怎么办?

解决方法

有趣的是,如果您能弄清楚如何将它们传递给 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
    }

}

我更进一步,为不同的计时函数定义了常量。 (我不知道为什么 Apple 没有定义这些。这看起来很荒谬,但你就是这样。)

我对 UIView.KeyframeAnimationOptions 的扩展如下所示:

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() 匹配选项中的标志很好奇。我编写了一些代码来记录两个 OptionSet 的所有值,这就是我得到的:

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 动画的缓入/缓出时间。

所有其他常量在两个 OptionSet 中都有唯一的值,这表明其他一些 UIView.AnimationOptions 可能适用于关键帧动画。不过,我只测试了时序曲线值,这些都按预期工作。

编辑 #2:

关键帧动画标志(如calculationModeLinear、calculationModeCubic 和calculationModeCubicPaced)和视图动画标志(如curveLinear、curveEaseInOut 等)如何交互并不是很明显,因为关键帧动画标志也与动画计时有关.我写了一个测试应用程序来看看他们是怎么做的。事实证明,UIView.AnimationOptions 时序曲线标志会影响整个关键帧动画的整体时序。 (整个关键帧动画开始和停止的方式。)

您可以从 github here 下载示例项目。

很难看到缓入/缓出 UIView 动画时间与立方关键帧动画选项之一相结合。使用关键帧计算模式线性模式更容易看到缓入/缓出。

以下是该组合的视频:

1

(注意青色方块在返回起点之前如何在动画矩形的右下角停止。)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?