![](/img/trans.png)
[英]How do I make DispatchGroup work consequently with DispatchQueue?
[英]How do I delay running a line of code until animations are finished? (DispatchGroup & DispatchQueue)
我在 Swift 5 (Xcode 13.4.1) 工作,我有 3 个动画应该在按下按钮后运行。 其中一个动画“旋转”由 function 定义。 旋转 animation 在持续时间结束后不会停止,它只是重新启动。 我正在尝试使用self.UI_Image_Name.layer.removeAllAnimations
。
我无法让我的代码等到动画完成才能运行removeAllAnimations
行。 我一直在尝试遵循本教程: 等待任务完成
这是我当前的代码:
@IBAction func flipButtonPress(_ sender: UIButton) {
// flipResult.image = results[Int.random(in: 0...1)]
self.animationGroup.enter()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now(), execute: { () -> Void in
//Slide coin image to middle of screen
UIView.animate(withDuration: 3, delay: 0,
options: [.curveEaseIn, .curveEaseOut],
animations: {
self.coinImage.frame.origin.y = 220
})
//Rotate Coin image
UIView.animate(withDuration: 11, delay: 3,
options: [.curveEaseIn, .curveEaseOut],
animations: {
self.coinImage.rotate()
})
//Fade away coin image
UIView.animate(withDuration: 5, delay: 6,
options: [],
animations: {
self.coinImage.alpha = 0.5
})
self.animationGroup.leave()
})
self.animationGroup.enter()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now(), execute: { () -> Void in
self.coinImage.layer.removeAllAnimations()
})
self.animationGroup.leave()
}
}
extension UIImageView{
func rotate() {
let rotation : CABasicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
rotation.toValue = NSNumber(value: (Double.pi * 2) * 22)
rotation.duration = 11
rotation.isCumulative = true
rotation.repeatCount = Float.greatestFiniteMagnitude
rotation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
rotation.beginTime = CACurrentMediaTime() + 3;
self.layer.add(rotation, forKey: "rotationAnimation")
}
}
好的,这里有很多东西,其中之一,你可以删除 animation 组,好像它的唯一目的是在动画完成时帮助运行代码,那么我们就不需要它了。
其次,动画带有completion
回调。 因此,将您的Fade away coin image
更改为:
UIView.animate(withDuration: 5, delay: 6, options: []) {
self.coinImage.alpha = 0.5
} completion: { _ in
self.coinImage.layer.removeAllAnimations()
}
这意味着在 6 秒延迟和 5 秒 animation 之后,硬币层动画将被移除
如果这不能产生预期的效果,那么您可以尝试这个(我个人尽量避免使用它,因为如果 animation 时间发生变化,它可能容易中断):
DispatchQueue.main.asyncAfter(deadline: .now() + <#Delay in seconds#>) {
<#code#>
}
这将在给定的秒数后运行闭包内的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.