我有一个函数可以开始播放异步运行的动画(在后台)。使用完成处理程序无限期地调用此动画(请参阅下文)。有没有办法在按下另一个按钮时关闭此功能?
这是我的代码:
func showAnimation() {
UIView.animate(withDuration: 1, animations: {
animate1(imageView: self.Anime, images: self.animation1)
}, completion: { (true) in
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
self.showAnimation() // replay first showAnimation
}
})
}
然后按下另一个按钮我们关闭上述功能
showAnimation().stop();
由于
答案 0 :(得分:4)
有很多方法可以做到这一点。最简单的方法是在asyncAfter
块中检查一个布尔属性(你应该正确地使用原子),如果它不是&#,请不要再次调用showAnimation()
39;是的。
您可以做的另一件事,以及我希望为更复杂的任务做些什么,是使用OperationQueue
代替DispatchQueue
。这允许您单独或全部取消操作,甚至暂停整个队列(显然不要暂停主队列或在其上调用removeAllOperations()
,因为可能还有其他操作与你的代码无关。)
答案 1 :(得分:3)
您可以向该类添加一个属性,作为指示是否应该运行动画的标志。
var runAnimation = true
func showAnimation() {
if !runAnimation { return }
UIView.animate(withDuration: 1, animations: {
animate1(imageView: self.Anime, images: self.animation1)
}, completion: { (true) in
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
if runAnimation {
self.showAnimation() // replay first showAnimation
}
}
})
}
然后在按钮处理程序中停止动画,你只需执行:
runAnimation = false
请注意,这不会停止当前运行的1秒动画。这只是阻止了更多的动画。
答案 2 :(得分:1)
您可以在函数之外提供变量,然后观察其值并处理您的任务。我可以给你一个解决方案:
class SomeClass {
private var shouldStopMyFunction: Bool = false // keep this private
public var deadline: TimeInterval = 0
func stopMyFunction() {
shouldStopMyFunction = true
}
func myFunction(completionHanlder: @escaping (String)->()) {
// -------
var isTaskRunning = true
func checkStop() {
DispatchQueue.global(qos: .background).async {
if self.shouldStopMyFunction, isTaskRunning {
isTaskRunning = false
completionHanlder("myFunction is forced to stop! ")
} else {
//print("Checking...")
checkStop()
}
}
}
checkStop()
// --------
// Start your task from here
DispatchQueue.global().async { // an async task for an example.
DispatchQueue.global().asyncAfter(deadline: .now() + self.deadline, execute: {
guard isTaskRunning else { return }
isTaskRunning = false
completionHanlder("My job takes \(self.deadline) seconds to finish")
})
}
}
}
并实施:
let anObject = SomeClass()
anObject.deadline = 5.0 // seconds
anObject.myFunction { result in
print(result)
}
let waitingTimeInterval = 3.0 // 6.0 // see `anObject.deadline`
DispatchQueue.main.asyncAfter(deadline: .now() + waitingTimeInterval) {
anObject.stopMyFunction()
}
结果waitingTimeInterval = 3.0
:myFunction is forced to stop!
结果waitingTimeInterval = 6.0
:My job takes 5.0 seconds to finish