【问题标题】:Create a continuously rotating square on the screen using animateKeyframesWithDuration使用 animateKeyframesWithDuration 在屏幕上创建一个连续旋转的正方形
【发布时间】:2014-10-30 23:22:47
【问题描述】:

我尝试使用下面的代码在屏幕上创建一个连续旋转的正方形。但我不知道为什么转速会发生变化。如何更改代码以使转速不变?我尝试了不同的UIViewKeyframeAnimationOptions,但似乎它们都不起作用。

override func viewDidLoad() {
    super.viewDidLoad()

    let square = UIView()
    square.frame = CGRect(x: 55, y: 300, width: 40, height: 40)
    square.backgroundColor = UIColor.redColor()
    self.view.addSubview(square)

    let duration = 1.0
    let delay = 0.0
    let options = UIViewKeyframeAnimationOptions.Repeat
        UIView.animateKeyframesWithDuration(duration, delay: delay, options: options, animations: {
        let fullRotation = CGFloat(M_PI * 2)

        UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 1/3, animations: {
            square.transform = CGAffineTransformMakeRotation(1/3 * fullRotation)
        })                        
        UIView.addKeyframeWithRelativeStartTime(1/3, relativeDuration: 1/3, animations: {
            square.transform = CGAffineTransformMakeRotation(2/3 * fullRotation)
        })                        
        UIView.addKeyframeWithRelativeStartTime(2/3, relativeDuration: 1/3, animations: {
            square.transform = CGAffineTransformMakeRotation(3/3 * fullRotation)
        })
        }, completion: {finished in
        })
    }         

【问题讨论】:

  • 1/3 给出了与 1.0/3.0 不同的结果。是这个问题吗?
  • 试图将第 9 行更改为 let options = UIViewKeyframeAnimationOptions.CalculationModeLinear|UIViewKeyframeAnimationOptions.Repeat 但没有帮助
  • 尝试将所有 1/3 更改为 1.0/3.0 。但无济于事
  • 您使用关键帧是否有原因?将 UIView.animateWithDuration(duration:delay:options:animations:completion:) 工作。我也遇到了关键帧版本的问题,但让这个版本可以工作。
  • @JMFR 我正在使用关键帧,因为我发现 animateWithDuration 不起作用。因为一个完整的 360 度旋转的开始和结束状态是等价的,Swift 没有在两者之间插入任何东西。如果您获得了 animateWithDuration 版本,能否提供更多详细信息?

标签: ios animation swift rotation repeat


【解决方案1】:

我之前遇到过同样的问题,这就是我的工作方式:

斯威夫特 2

let raw = UIViewKeyframeAnimationOptions.Repeat.rawValue | UIViewAnimationOptions.CurveLinear.rawValue
let options = UIViewKeyframeAnimationOptions(rawValue: raw)

斯威夫特 3,4,5

let raw = UIView.KeyframeAnimationOptions.repeat.rawValue | UIView.AnimationOptions.curveLinear.rawValue
let options = UIView.KeyframeAnimationOptions(rawValue: raw)

我在放弃之前发现了这个问题。我认为没有关于它的文档,但它确实有效。

【讨论】:

  • 今天你是我的英雄。谢谢你。
【解决方案2】:

这真的很奇怪...UIView.animateKeyframesWithDuration 没有像我期望的那样工作,UIViewKeyframeAnimationOptions.CalculationModeLinear|UIViewKeyframeAnimationOpti‌​ons.Repeat 通过选项传入。

如果您使用非块方法创建关键帧动画(见下文),旋转会按预期重复。

如果我发现为什么基于块的选项不起作用,我会尝试并记住在此处更新答案!

override func viewDidLoad() {
    super.viewDidLoad()


    let square = UIView()
    square.frame = CGRect(x: 55, y: 300, width: 40, height: 40)
    square.backgroundColor = UIColor.redColor()
    self.view.addSubview(square)

    let fullRotation = CGFloat(M_PI * 2)

    let animation = CAKeyframeAnimation()
    animation.keyPath = "transform.rotation.z"
    animation.duration = 2
    animation.removedOnCompletion = false
    animation.fillMode = kCAFillModeForwards
    animation.repeatCount = Float.infinity
    animation.values = [fullRotation/4, fullRotation/2, fullRotation*3/4, fullRotation]

    square.layer.addAnimation(animation, forKey: "rotate")

}

【讨论】:

    【解决方案3】:

    添加UIViewKeyframeAnimationOptionCalculationModeLinear 做你的关键帧选项。 UIView 动画的默认行为是“缓入/缓出”动画。即,开始缓慢,加快速度,然后在接近尾声时再次减速。

    【讨论】:

    • 感谢您的回答。我将选项更改为“ let options = UIViewKeyframeAnimationOptions.CalculationModeLinear|UIViewKeyframeAnimationOptions.Repeat”,但似乎得到了相同的结果。
    【解决方案4】:

    AFAIU,这是因为默认动画曲线是UIViewAnimationOption.CurveEaseInOut

    很遗憾,UIViewKeyframeAnimationOptions 没有更改曲线的选项,但您可以手动添加它们!

    使用这个扩展:

    斯威夫特 2

    extension UIViewKeyframeAnimationOptions {
        static var CurveEaseInOut: UIViewKeyframeAnimationOptions { return UIViewKeyframeAnimationOptions(rawValue: UIViewAnimationOptions.CurveEaseInOut.rawValue) }
        static var CurveEaseIn: UIViewKeyframeAnimationOptions { return UIViewKeyframeAnimationOptions(rawValue: UIViewAnimationOptions.CurveEaseIn.rawValue) }
        static var CurveEaseOut: UIViewKeyframeAnimationOptions { return UIViewKeyframeAnimationOptions(rawValue: UIViewAnimationOptions.CurveEaseOut.rawValue) }
        static var CurveLinear: UIViewKeyframeAnimationOptions { return UIViewKeyframeAnimationOptions(rawValue: UIViewAnimationOptions.CurveLinear.rawValue) }
    }
    

    Swift 3、4、5

    extension UIView.KeyframeAnimationOptions {
        static var curveEaseInOut: UIView.KeyframeAnimationOptions { return UIView.KeyframeAnimationOptions(rawValue: UIView.AnimationOptions.curveEaseInOut.rawValue) }
        static var curveEaseIn: UIView.KeyframeAnimationOptions { return UIView.KeyframeAnimationOptions(rawValue: UIView.AnimationOptions.curveEaseIn.rawValue) }
        static var curveEaseOut: UIView.KeyframeAnimationOptions { return UIView.KeyframeAnimationOptions(rawValue: UIView.AnimationOptions.curveEaseOut.rawValue) }
        static var curveLinear: UIView.KeyframeAnimationOptions { return UIView.KeyframeAnimationOptions(rawValue: UIView.AnimationOptions.curveLinear.rawValue) }
    }
    

    现在您可以在UIView.animateKeyframesWithDuration 方法中使用曲线选项

    斯威夫特 2

    let keyframeOptions: UIViewKeyframeAnimationOptions = [.Repeat, .CurveLinear]
    UIView.animateKeyframesWithDuration(duration, delay: delay, options: keyframeOptions, animations: {
        // add key frames here
    }, completion: nil)
    

    Swift 3、4、5

    let keyframeOptions: UIView.KeyframeAnimationOptions = [.repeat, .curveLinear]
    UIView.animateKeyframes(withDuration: duration, delay: delay, options: keyframeOptions, animations: {
        // add key frames here
    }, completion: nil)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-22
      • 1970-01-01
      相关资源
      最近更新 更多