2015-01-10 15 views
23

Próbuję animować obiekt UIImageView, a następnie ukryć widok obrazu po zakończeniu animacji. Jednak widok obrazu zostanie ukryty przed ukończeniem animacji. Przyjrzałem się podobnym pytaniom i zalecają implementację detektora animacji lub wykonanie kodu .hidden w kodzie animacji po zakończeniu, ale nie jestem pewien, jak wpłynąć na to w ramach funkcji shakeView() poniżej.Czekaj na ukończenie animacji Swift przed wykonaniem kodu

Jak wyświetlić animację wstrząsania i ukryć widok obrazu dopiero po ukończeniu animacji?

Animacja nazywa się stosując następujący kod:

shakeView(image1!) 
shakeView(image2) 
image1!.hidden = true 
image2.hidden = true 

Sama funkcja animacja wygląda tak:

func shakeView(iv: UIImageView){ 
    var shake:CABasicAnimation = CABasicAnimation(keyPath: "position") 
    shake.duration = 0.1 
    shake.repeatCount = 2 
    shake.autoreverses = true 

    var from_point:CGPoint = CGPointMake(iv.center.x - 5, iv.center.y) 
    var from_value:NSValue = NSValue(CGPoint: from_point) 

    var to_point:CGPoint = CGPointMake(iv.center.x + 5, iv.center.y) 
    var to_value:NSValue = NSValue(CGPoint: to_point) 

    shake.fromValue = from_value 
    shake.toValue = to_value 
    iv.layer.addAnimation(shake, forKey: "position") 
} 
+0

Patrz „wykrywania koniec animacja” w https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreAnimation_guide/CreatingBasicAnimations/CreatingBasicAnimations.html#//apple_ref/doc/ uid/TP40004514-CH3-SW1 – Paulw11

Odpowiedz

53

można użyć CATransaction zadzwonić blok zakończeniu po zakończeniu animacji.

func shakeView(iv: UIImageView){ 

    CATransaction.begin() 
    CATransaction.setCompletionBlock({ 
     iv.hidden = true 
    }) 
    var shake:CABasicAnimation = CABasicAnimation(keyPath: "position") 
    shake.duration = 0.1 
    shake.repeatCount = 21 
    shake.autoreverses = true 

    var from_point:CGPoint = CGPointMake(iv.center.x - 5, iv.center.y) 
    var from_value:NSValue = NSValue(CGPoint: from_point) 

    var to_point:CGPoint = CGPointMake(iv.center.x + 5, iv.center.y) 
    var to_value:NSValue = NSValue(CGPoint: to_point) 

    shake.fromValue = from_value 
    shake.toValue = to_value 
    iv.layer.addAnimation(shake, forKey: "position") 
    CATransaction.commit() 
} 

Można także zgrupować obie animacje razem w postaci CATransaction w następujący sposób.

func shakeView(iv: UIImageView){ 
    var shake:CABasicAnimation = CABasicAnimation(keyPath: "position") 
    shake.duration = 0.1 
    shake.repeatCount = 21 
    shake.autoreverses = true 

    var from_point:CGPoint = CGPointMake(iv.center.x - 5, iv.center.y) 
    var from_value:NSValue = NSValue(CGPoint: from_point) 

    var to_point:CGPoint = CGPointMake(iv.center.x + 5, iv.center.y) 
    var to_value:NSValue = NSValue(CGPoint: to_point) 

    shake.fromValue = from_value 
    shake.toValue = to_value 
    iv.layer.addAnimation(shake, forKey: "position") 
} 

override func viewDidLoad() { 
    CATransaction.begin() 

    CATransaction.setCompletionBlock({ 
     self.image1.hidden = true 
     self.image2.hidden = true 
    }) 
    shakeView(image1) 
    shakeView(image) 
    CATransaction.commit() 
} 
+0

Pierwsza implementacja działała idealnie. Wymieniłem UIImageView na UIButton i kod działał bez problemu. Dzięki! – zeeshan

13

Jak Paulw11 nawiązywał w swoim komentarzu, można użyć metody animationDidStop: mowa w doktorzy. Ponadto, należy dodać klucz do ciebie, tak aby twoja metoda wiedziała, który z nich został zakończony.

Więc w swojej metodzie wytrząsania dodać parę wartości klucza do identyfikacji animacji i ustaw przenoszą na siebie, ex:

func shakeView(iv: UIImageView){ 

    var shake:CABasicAnimation = CABasicAnimation(keyPath: "position") 
    shake.duration = 0.1 
    shake.repeatCount = 2 
    shake.autoreverses = true 

    // Add these two lines: 
    shake.setValue("shake", forKey: "animationID") 
    shake.delegate = self 

    // ... 

Następnie dodać metodę animationDidStop: delegata w celu poinformowania o tym, kiedy animacja jest pełna, dzięki czemu można rozpocząć wykonywanie kodu:

override func animationDidStop(anim: CAAnimation!, finished flag: Bool) { 
    // Unwrap the optional value for the key "animationID" then 
    // if it's equal to the same value as the relevant animation, 
    // execute the relevant code 
    if let animationID: AnyObject = anim.valueForKey("animationID") { 
     if animationID as NSString == "shake" { 
      // execute code 
     } 
    } 
} 
+0

Dobrze wiedzieć, rozważymy dodanie do wdrożenia, dziękuję. – zeeshan

+1

Szukałem tego dokładnego przykładu. Dzięki! – OpherV

+1

Nie zapomnij dostosować CAAnimationDelegate w swoim viewController –

Powiązane problemy