减慢 CAGradientLayer 动画

Posted

技术标签:

【中文标题】减慢 CAGradientLayer 动画【英文标题】:Slowing down CAGradientLayer animation 【发布时间】:2017-09-21 13:44:57 【问题描述】:

我想慢慢地制作一个三色渐变的动画。

我有一个自定义的UIView,如下所示:

class MyView: UIView, CAAnimationDelegate 

  lazy var gradientLayer: CAGradientLayer = 
        let l = CAGradientLayer()
        l.frame = self.frame
        l.colors = self.colors
        l.startPoint = CGPoint(x: 0, y: 0)
        l.endPoint = CGPoint(x: 1, y: 0)
        l.mask = self.textLayer
        return l
    ()

    lazy var textLayer: CATextLayer = 
        let l = CATextLayer()
        l.frame = self.frame
        l.string = "test".uppercased()
        l.fontSize = 23
        return l
    ()

    var colors: [CGColor] =  [
            UIColor.red.cgColor,
            UIColor.purple.cgColor,
            UIColor.blue.cgColor
            ]

    init() 
    ...
    self.layer.addSublayer(gradientLayer)

    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    func animate() 

      var newColors = colors
      let lastColor: CGColor = newColors.last!
      newColors.removeLast()
      newColors.insert(lastColor, at: 0)

      colors: newColors
      gradientLayer.colors = newColors

      let a = CABasicAnimation(keyPath:"colors")
      a.toValue = newColors
      a.duration = 0.1
      a.isRemovedOnCompletion = true
      a.fillMode = kCAFillModeForwards
      a.delegate = self

      gradientLayer.add(a, forKey:"animateGradient")

    

    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) 

          animate()
    


这可行,但速度非常快。我怎样才能减慢动画速度,而不会变得块状? 我是否必须在 colors 数组中添加几百种颜色,以便它有足够的循环时间?

谢谢

【问题讨论】:

会不会只是将 a.duration = 0.1 更改为更慢的值? 使duration 变小会使动画更快。让它变大,你就没有流畅的动画。它更像是一个跳跃,而不是动画。 您可以使用UIColor red green blue alpha 方法并在动画块中更改它们的值。但是你需要想出一个算法来组合RGB,以覆盖你的三种原色。 【参考方案1】:

除非我在您的代码中遗漏了某些内容,否则您没有在动画中设置 fromValue。当然,在将颜色切换为 newColors 之前,您需要将其设置为以前的颜色值:

func animate() 
  let oldColors = colors
  var newColors = colors
  let lastColor: CGColor = newColors.last!
  newColors.removeLast()
  newColors.insert(lastColor, at: 0)

  colors = newColors
  gradientLayer.colors = newColors

  let a = CABasicAnimation(keyPath:"colors")
  // New line here ->
  a.fromValue = oldColors
  a.toValue = newColors
  a.duration = 0.1
  a.isRemovedOnCompletion = true
  a.fillMode = kCAFillModeForwards
  a.delegate = self

  gradientLayer.add(a, forKey:"animateGradient")


这将是您没有真正获得动画的原因 - 您的代码被有效地设置为创建延迟的快照过渡。

【讨论】:

我正在制作一个动画,它太快了...你看到它飞过...我希望它需要大约一分钟才能完成一个周期。 如果您尝试我的代码并将持续时间更改为 60,它会变慢吗(抱歉,我不在办公桌前,无法测试代码)?

以上是关于减慢 CAGradientLayer 动画的主要内容,如果未能解决你的问题,请参考以下文章

CAGradientLayer 颜色更改动画未执行

ios 动画 利用CAGradientLayer实现动画

如何为导航栏设置 CAGradientLayer 动画

为啥我的 CAGradientLayer 为所有更改设置动画?

CAGradientLayer实现色差动画

动画视图的子视图不适用于 CAGradientLayer [关闭]