Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop a Function from Running in Swift 3.0

I have a function that starts playing an animation that is running asynchronously (in the background). This animation is called indefinitely using a completion handler (see below). Is there a way to close this function upon pressing another button?

Here is my code:

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
        }
    }) 
 }

Then upon pressing another button we closeout the above function

showAnimation().stop();

Thanks

like image 524
Server Programmer Avatar asked Jan 03 '18 21:01

Server Programmer


People also ask

How to delay a function in Swift?

In Swift 4.2 and Xcode 10.1 You have 4 ways total to delay. Out of these option 1 is preferable to call or execute a function after some time. The sleep () is least case in use. Option 1. Option 2. perform (#selector (yourFuncHere2), with: nil, afterDelay: 5.0) //Your function here @objc func yourFuncHere2 () { print ("this is...")

What is sleep method in Swift 3?

Comparison between different approaches in swift 3.0 1. Sleep This method does not have a call back. Put codes directly after this line to be executed in 4 seconds. It will stop user from iterating with UI elements like the test button until the time is gone.

How do you call a function in Swift?

You give a function a name that identifies what it does, and this name is used to “call” the function to perform its task when needed. Swift’s unified function syntax is flexible enough to express anything from a simple C-style function with no parameter names to a complex Objective-C-style method with names and argument labels for each parameter.

What is an in-out parameter in Swift?

Parameters can provide default values to simplify function calls and can be passed as in-out parameters, which modify a passed variable once the function has completed its execution. Every function in Swift has a type, consisting of the function’s parameter types and return type.


2 Answers

You can add a property to the class to act as a flag indicating whether the animation should be run or not.

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
            }
        }
    }) 
}

Then in the button handler to stop the animation you simply do:

runAnimation = false

Note that this does not stop the currently running 1 second animation. This just prevent any more animations.

like image 167
rmaddy Avatar answered Sep 26 '22 14:09

rmaddy


There are a lot of ways to do this. The simplest is to have a Boolean property (which you should make properly atomic) that you check in your asyncAfter block, and don't just don't call showAnimation() again if it's true.

Another thing you can do, and what I like to do for more complex tasks, is to use OperationQueue instead of DispatchQueue. This allows you to cancel operations, either individually or all at once, or even suspend the whole queue (obviously don't suspend the main queue or call removeAllOperations() on it, though, since there may be other operations in there unrelated to your code).

like image 32
Charles Srstka Avatar answered Sep 26 '22 14:09

Charles Srstka