2017-09-21 132 views
0

我想动画一个三色渐变缓慢放慢CAGradientLayer动画

我有一个自定义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阵列添加几百种颜色才能使其足以循环使用?

感谢

+0

wouldnt它只是改变a.duration = 0.1到更慢的东西? – rambossa

+0

使'duration'较小会导致动画变得更快。使其变大并且您没有流体动画。它更像是一个跳跃,而不是动画。 – Joseph

+0

您可以使用'UIColor''红色''绿色''蓝色''alpha'方法并在您的动画块中更改它们的值。但是你需要想出一个算法,它能够以覆盖你的三原色的方式完成RGB的组合。 –

回答

0

除非我失去了在你的代码的东西你没有设置动画中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") 

} 

这将是你是不是真的让你的代码有效成立的animation-创建延迟卡的原因过渡。

+0

我收到的动画太快了......你看到它飞了......我希望它能在一个周期内完成一分钟。 – Joseph

+0

如果您尝试我的代码并将持续时间更改为60,是否会减慢速度(道歉,我远离桌面,无法测试代码)? – Sparky