2017-09-21 139 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