web-dev-qa-db-ja.com

Swiftアニメーションが完了するのを待ってからコードを実行します

UIImageViewをアニメーション化し、アニメーションの完了後に画像ビューを非表示にしようとしています。ただし、アニメーションが完了する前に画像ビューは非表示になります。私は同様の質問を見て、完了時にアニメーションリスナーを実装するか、アニメーションコード内で.hiddenコードを実行することを推奨していますが、以下のshakeView()関数内でこれに影響を与える方法がわかりません。

アニメーションが完了した後にのみシェイクアニメーションを表示して画像ビューを非表示にするにはどうすればよいですか?

アニメーションは、次のコードを使用して呼び出されます。

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

アニメーション関数自体は次のようになります。

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")
}
29
zeeshan

CATransactionを使用して、アニメーションの完了後に完了ブロックを呼び出すことができます。

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()
}

または、次のようにCATransactionで両方のアニメーションをグループ化することもできます。

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()
}
66
rakeshbs

Paulw11が彼のコメントで示唆したように、animationDidStop:ドキュメントに記載されているメソッド。しかし、さらに、キーを追加する必要がありますCABasicAnimation/CAAnimationあなたのanimationDidStop:メソッドは、特にどれが完了したかを知っています。

そのため、シェイクメソッドに値とキーのペアを追加してアニメーションを識別し、デリゲートをselfに設定します。例:

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

    // ...

次に、animationDidStop:メソッドを委任して、アニメーションの完了を通知するため、コードの実行を開始できます。

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
        }
    }
}
15
Lyndsey Scott