如何阻止函数在Swift 3.0中运行

时间:2018-01-03 21:48:49

标签: ios swift uiviewanimation

我有一个函数可以开始播放异步运行的动画(在后台)。使用完成处理程序无限期地调用此动画(请参阅下文)。有没有办法在按下另一个按钮时关闭此功能?

这是我的代码:

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

由于

3 个答案:

答案 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.0myFunction is forced to stop!

结果waitingTimeInterval = 6.0My job takes 5.0 seconds to finish