ios 在执行代码之前等待 Swift 动画完成
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27882016/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Wait for Swift animation to complete before executing code
提问by zeeshan
I am trying to animate a UIImageView and then hide the image view after animation is complete. However the imageview gets hidden before the animation is completed. I looked at similar questions and they recommend implementing an animation listener or executing the .hidden code within the animation code upon completion however I'm not sure how to affect this within the shakeView() function below.
我正在尝试为 UIImageView 设置动画,然后在动画完成后隐藏图像视图。但是,在动画完成之前,图像视图会被隐藏。我查看了类似的问题,他们建议在完成后实现动画侦听器或在动画代码中执行 .hidden 代码,但是我不确定如何在下面的shakeView() 函数中影响它。
How do I show the shake animation and hide the image view only after the animation is complete?
如何仅在动画完成后显示抖动动画并隐藏图像视图?
Animation is called using the following code:
使用以下代码调用动画:
shakeView(image1!)
shakeView(image2)
image1!.hidden = true
image2.hidden = true
The animation function itself looks like this:
动画函数本身看起来像这样:
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")
}
回答by rakeshbs
You can use a CATransaction
to call a completion block after the animation completes.
您可以CATransaction
在动画完成后使用 a来调用完成块。
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()
}
Or you can also group both animations together in a CATransaction
as follows.
或者您也可以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()
}
回答by Lyndsey Scott
As Paulw11 alluded to in his comment, you can use the animationDidStop:
method mentioned in the docs. But furthermore, you should add a key to you CABasicAnimation/CAAnimation
objects such that your animationDidStop:
method knows which one in particular has completed.
正如 Paulw11 在他的评论中提到的,您可以使用animationDidStop:
文档中提到的方法。但此外,您应该为您的CABasicAnimation/CAAnimation
对象添加一个键,以便您的animationDidStop:
方法知道哪个特定已完成。
So in your shake method add a value-key pair to identify the animation and set the delegate to self, ex:
所以在你的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
// ...
Then add the animationDidStop:
delegate method to alert you as to when the animation is complete so you can start executing your code:
然后添加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
}
}
}