2016-05-26 10 views
6

Desidero rianimare lo sfondo sfumato con colori diversi durante l'animazione. Posso animare correttamente il colore del gradiente con questo codice.Ri-Animare Sfondo sfumato con colore diverso in rapido in ios

let dayTopColor = CommonUtils.colorWithHexString("955EAC") 
let dayBottomColor = CommonUtils.colorWithHexString("9F3050") 
let dayToTopColor = CommonUtils.colorWithHexString("D15B52") 
let dayToBottomColor = CommonUtils.colorWithHexString("CC4645") 
let nightTopColor = CommonUtils.colorWithHexString("2D5E7C") 
let nightBottomColor = CommonUtils.colorWithHexString("19337D") 
let nightToTopColor = CommonUtils.colorWithHexString("21334E") 
let nightToBottomColor = CommonUtils.colorWithHexString("101A55") 
var isInSaudiArabia = false 
var gradient : CAGradientLayer? 
var toColors : AnyObject? 
var fromColors : AnyObject? 

func animateBackground(){ 
     var layerToRemove: CAGradientLayer? 
     for layer in self.view.layer.sublayers!{ 
      if layer.isKindOfClass(CAGradientLayer) { 
       layerToRemove = layer as? CAGradientLayer 
      } 
     } 
     layerToRemove?.removeFromSuperlayer() 

      self.gradient!.colors = [nightTopColor.CGColor, nightBottomColor.CGColor] 
      self.toColors = [nightToTopColor.CGColor, nightToBottomColor.CGColor] 

     self.view.layer.insertSublayer(self.gradient!, atIndex: 0) 
     animateLayer() 
    } 

    func animateLayer(){ 

     self.fromColors = self.gradient!.colors! 
     self.gradient!.colors = self.toColors as? [AnyObject] 
     let animation : CABasicAnimation = CABasicAnimation(keyPath: "colors") 
     animation.delegate = self 
     animation.fromValue = fromColors 
     animation.toValue = toColors 
     animation.duration = 3.50 
     animation.removedOnCompletion = true 
     animation.fillMode = kCAFillModeForwards 
     animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) 
     animation.delegate = self 

     self.gradient!.addAnimation(animation, forKey:"animateGradient") 
    } 

    override func animationDidStop(anim: CAAnimation, finished flag: Bool) { 

     self.toColors = self.fromColors; 
     self.fromColors = self.gradient!.colors! 

     animateLayer() 
    } 

CommonUtils.colorWithHexString() è una funzione che converte colore esadecimale per UIColor. Quando tento di cambiare il colore di sfondo con il colore del giorno durante l'animazione, il colore del gradiente di sfondo si è sfarfallato.

C'è qualcuno che conosce la soluzione.

risposta

6

Il problema è che quando si rimuove il livello, si interrompe l'animazione. Ma quando l'animazione si interrompe, viene ancora chiamato il numero animationDidStop, che sta iniziando una nuova animazione. Quindi, stai rimuovendo il livello, che interrompe l'animazione, ne avvia immediatamente un altro, ma in quel momento inizierai un'altra animazione. Hai duellando le animazioni.

È possibile controllare flag per vedere se l'animazione è stata completata correttamente prima di animationDidStop deve chiamare animateLayer.

override func animationDidStop(anim: CAAnimation, finished flag: Bool) { 
    if flag { 
     toColors = fromColors; 
     fromColors = gradient!.colors! 

     animateLayer() 
    } 
} 

Personalmente, non sono sicuro del motivo per cui si sta rimuovendo e aggiungendo e rimuovendo il livello. E se lo fossi, non sono sicuro del motivo per cui non ti limiti solo allo gradient?.removeFromSuperlayer() piuttosto che a scorrere tra i livelli.

Indipendentemente da ciò, mi piacerebbe solo a mantenere lo strato gradient lì, resta che verificare la presentationLayer e avviare l'animazione da lì:

class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     fromColors = [dayTopColor.CGColor, dayBottomColor.CGColor] 
     toColors = [dayToTopColor.CGColor, dayToBottomColor.CGColor] 

     gradient = CAGradientLayer() 
     gradient!.colors = fromColors! 
     gradient!.frame = view.bounds 
     view.layer.addSublayer(gradient!) 

     animateLayer() 
    } 

    let dayTopColor = CommonUtils.colorWithHexString("955EAC") 
    let dayBottomColor = CommonUtils.colorWithHexString("9F3050") 
    let dayToTopColor = CommonUtils.colorWithHexString("D15B52") 
    let dayToBottomColor = CommonUtils.colorWithHexString("CC4645") 

    let nightTopColor = CommonUtils.colorWithHexString("2D5E7C") 
    let nightBottomColor = CommonUtils.colorWithHexString("19337D") 
    let nightToTopColor = CommonUtils.colorWithHexString("21334E") 
    let nightToBottomColor = CommonUtils.colorWithHexString("101A55") 

    var gradient : CAGradientLayer? 
    var toColors : [CGColor]? 
    var fromColors : [CGColor]? 

    var day = true 

    func toggleFromDayToNight() { 
     day = !day 

     if day { 
      fromColors = [dayTopColor.CGColor, dayBottomColor.CGColor] 
      toColors = [dayToTopColor.CGColor, dayToBottomColor.CGColor] 
     } else { 
      fromColors = [nightTopColor.CGColor, nightBottomColor.CGColor] 
      toColors = [nightToTopColor.CGColor, nightToBottomColor.CGColor] 
     } 

     let colors = (gradient!.presentationLayer() as! CAGradientLayer).colors // save the in-flight current colors 
     gradient!.removeAnimationForKey("animateGradient")      // cancel the animation 
     gradient!.colors = colors            // restore the colors to in-flight values 
     animateLayer()               // start animation 
    } 

    func animateLayer() { 
     let animation : CABasicAnimation = CABasicAnimation(keyPath: "colors") 
     animation.fromValue = gradient!.colors 
     animation.toValue = toColors 
     animation.duration = 3.50 
     animation.removedOnCompletion = true 
     animation.fillMode = kCAFillModeForwards 
     animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) 
     animation.delegate = self 

     gradient!.colors = toColors 

     gradient!.addAnimation(animation, forKey:"animateGradient") 
    } 

    override func animationDidStop(anim: CAAnimation, finished flag: Bool) { 
     if flag { 
      swap(&toColors, &fromColors) 
      animateLayer() 
     } 
    } 

    @IBAction func didTapButton() { 
     toggleFromDayToNight() 
    } 

} 
+0

E 'grande risposta, ho provato con questo e risolto il mio problema. Molte grazie. –

Problemi correlati