【问题标题】:how to set animation curve when using keyframe animation in ios?在ios中使用关键帧动画时如何设置动画曲线?
【发布时间】:2014-01-05 11:58:03
【问题描述】:

使用UIView的关键帧动画时如何设置动画曲线:

animateKeyframesWithDuration:delay:options:animations:completion:

我在动画块中所做的一切似乎都是线性的(除非我使用 UIViewKeyframeAnimationOptionCalculationModeCubic 选项,但这不是我想要的)。

在使用常规动画时,我想在动画上设置缓动曲线,例如 UIViewAnimationOptionCurveEaseOut 选项:

animateWithDuration:delay:options:animations:completion:

【问题讨论】:

    标签: ios animation ios7 core-animation


    【解决方案1】:

    Swift 2.0 不允许将 UIViewAnimationOptions 转换为 UIViewKeyframeAnimationOptions。它也不允许|他们在一起。

    但是,UIViewKeyframeAnimationOptions 有一个初始化器,它采用 rawValue。因此,以下代码可以将UIViewAnimationOptions 放入UIViewKeyframeAnimationOptions

    let animationOptions: UIViewAnimationOptions = .CurveEaseOut
    let keyframeAnimationOptions: UIViewKeyframeAnimationOptions = UIViewKeyframeAnimationOptions(rawValue: animationOptions.rawValue)
    

    然后我可以将keyframeAnimationOptions 传递给animateKeyframesWithDuration,一切正常。

    对于 Swift 4:

    let animationOptions = AnimationOptions.curveEaseOut
    let options = KeyframeAnimationOptions(rawValue: animationOptions.rawValue)
    

    【讨论】:

    • 如何增加.CurveEaseOut的效果?谢谢,很好的答案!
    • 这似乎不适用于 swift3 及更高版本。动画仍然呈现线性。有没有人找到适用于 swift4 的解决方案?
    【解决方案2】:

    实际上,您可以使用与 animateWithDuration:delay:options:animations:completion: 相同的曲线标志。只需在调用 animateKeyframesWithDuration:delay:options:animations:completion:

    时将它们与其他选项“二进制或”

    文档令人困惑,但确实有效。

    您可以使用的曲线值为:

    UIViewAnimationOptionCurveEaseInOut = 0 << 16,
    UIViewAnimationOptionCurveEaseIn    = 1 << 16,
    UIViewAnimationOptionCurveEaseOut   = 2 << 16,
    UIViewAnimationOptionCurveLinear    = 3 << 16,
    

    你得到的默认动画曲线是0,或者ease-in,ease-out。

    【讨论】:

    • 太棒了!工作正常。很奇怪,这不在文档中,特别是因为它们默认为非线性...
    • 好吧,在尝试了所有的 KeyFrameOptions 之后,我回到了这个我必须开始的地方。它会发出警告,但效果很好:)
    • 这不适用于 Swift,因为一切都是强类型的!
    • @fatuhoku,你应该可以通过类型转换来克服这个问题
    • 在 Swift 4 中,UIViewAnimationOptionCurveLinear 是:UIViewKeyframeAnimationOptions(rawValue: (3 &lt;&lt; 16))
    【解决方案3】:

    这是我想出的一个不错且干净的 Swift 解决方案:

    extension UIViewKeyframeAnimationOptions {
    
        init(animationOptions: UIViewAnimationOptions) {
            rawValue = animationOptions.rawValue
        }
    
    }
    

    用法:

    UIViewKeyframeAnimationOptions(animationOptions: .CurveEaseOut)
    

    【讨论】:

    • Swift 5: self.init(rawValue: animationOptions.rawValue)
    【解决方案4】:

    @eskimwier 的答案在尝试将 animateKeyframes(withDuration:delay:options:animations:completion:) 的曲线设置为 linear 时对我不起作用。这是在 Swift 3、Xcode 8.2.1 中。

    我的动画似乎默认为easeInOut(启动慢,中间快,最后慢)。 Apple 是否更改了默认曲线?

    无论如何,我想要一条线性曲线,并尝试了上面建议的方法来使用 UIViewAnimationOptions 和关键帧动画:

    let animationOptions: UIViewAnimationOptions = .curveLinear
    var keyframeAnimationOptions: UIViewKeyframeAnimationOptions = UIViewKeyframeAnimationOptions(rawValue: animationOptions.rawValue)
    
    UIView.animateKeyframes(withDuration: 3, delay: 0, options: [keyframeAnimationOptions], animations: {
        //... animations here ...
    }, completion: nil)
    

    这没有效果。唯一对我有用的是在调用 animateKeyframes 之前执行此操作:

    UIView.setAnimationCurve(UIViewAnimationCurve.linear)
    

    【讨论】:

    • 我尝试了这两个建议。第一个选项(keyframeAnimationOptions 对我有用。
    【解决方案5】:

    如果你使用关键帧,你必须自己定义曲线。如果你添加线性关键帧,你就有一个线性动画。如果你添加非线性关键帧,你会得到一个非线性动画。

    frameStartTime 是您的朋友...它在关键帧之间始终是线性的(或节奏/立方/立方节奏,如UIViewKeyframeAnimationOptionCalculationMode 中定义的那样)

    UIViewKeyframeAnimationOptionCalculationModeLinear     = 0 << 9,
    UIViewKeyframeAnimationOptionCalculationModeDiscrete   = 1 << 9,
    UIViewKeyframeAnimationOptionCalculationModePaced      = 2 << 9,
    UIViewKeyframeAnimationOptionCalculationModeCubic      = 3 << 9,
    UIViewKeyframeAnimationOptionCalculationModeCubicPaced = 4 << 9
    

    要计算正确的计时值,您可以将此作为参考: RBBEasingFunction

    例如EaseInOutQuad 像这样(其中 t 是动画中的相对时间):

    if (t < 0.5) {
        return 2 * t * t;
    } else {
        return -1 + (4 - 2 * t) * t;
    }
    

    【讨论】:

      【解决方案6】:

      为关键帧动画设置动画曲线的一种简单方法是将关键帧动画包裹在 UIViewPropertyAnimator 对象中:

      let animator = UIViewPropertyAnimator(duration: 0.5, curve: .linear) {
      
          // withDuration: 0 means inherited duration from UIViewPropertyAnimator
          UIView.animateKeyframes(withDuration: 0, delay: 0, animations: {
              UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration:0.5) {
                  // modify view's properties
              }
      
              // more keyframes
          })
      }
      
      animator.startAnimation()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-04
        • 2021-11-01
        相关资源
        最近更新 更多