在执行代码之前等待 Swift 动画完成

Posted

技术标签:

【中文标题】在执行代码之前等待 Swift 动画完成【英文标题】:Wait for Swift animation to complete before executing code 【发布时间】:2015-01-10 22:50:07 【问题描述】:

我正在尝试为 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")

【问题讨论】:

参见developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…中的“检测动画结束” 【参考方案1】:

您可以在动画完成后使用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()

【讨论】:

第一个实现完美运行。我用 UIButton 替换了 UIImageView 并且代码没有问题。谢谢!【参考方案2】:

正如 Paulw11 在他的评论中提到的,您可以使用文档中提到的 animationDidStop: 方法。但此外,您应该为您的 CABasicAnimation/CAAnimation 对象添加一个键,以便您的 animationDidStop: 方法知道哪个特别完成了。

所以在你的shake方法中添加一个值-键对来识别动画并将代理设置为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
        
    

【讨论】:

很高兴知道,将考虑添加到实施中,谢谢。 正在寻找这个确切的例子。谢谢! 别忘了在你的 viewController 中遵守 CAAnimationDelegate

以上是关于在执行代码之前等待 Swift 动画完成的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX 在转到下一个方法之前等待动画方法完成

SCNAction 完成处理程序等待手势执行

UIImageView 等待动画完成

如何在textview上进行序列动画(swift3)

让 Jquery 函数等待动画完成

swift 4 - segue 动画完成后如何在目标视图控制器中运行代码?