How to stop an animation

(swift, storyboards, macOS)

Can I stop or pause an animation?

(I could find how to remove it: view1.layer?.removeAllAnimations()

Here is the official documentation but I do not understand: https://developer.apple.com/documentation/uikit/uiviewanimating/1649843-pauseanimation)

    @IBAction func fadeOut(_ sender: NSButton) {
        NSAnimationContext.runAnimationGroup({ (context) in
            context.duration = 5.0
            view1.animator().alphaValue = 0
        })
    }

You can do this (I added print to see what's happening:

    @IBAction func startAnimation(_ sender: NSButton) {
        NSAnimationContext.runAnimationGroup({ (context) in
            print("Start", view1.alphaValue)
            context.duration = 5.0
            view1.animator().alphaValue = 0
            print("End", view1.alphaValue)
        }) { // Completion
            print("Completed", self.view1.alphaValue)
            self.view1.alphaValue = 1.0  // You may need to reset at the end ?
        }
    }
    
    @IBAction func stopAnimation(_ sender: NSButton) {
        print("Stop")
        view1.layer?.removeAllAnimations()
    }

When you stop, animation ends immediately and completion handler is called.

Hope that helps.

I want to click stop/pause and the animation stop at that point, at some % between 0 and 1 alphaValue

I have not found a direct way to do it. But here is a workaround.

At start of animation:

  • get the alphaValue: initAlpha
  • get the time

In the completion, if elapsed is less than the set duration (here 5.0), which means animation was stopped:

  • compute elapsedTime since beginning of animation
  • compute what should be alpha at this time, if "normal" endValue (0) is endAlpha and normalDuration (5.0):
let deltaAlpha = (initAlpha - endAlpha) * (elapsed / normalDuration)
  • and set alpha inaccordingly:
self.view1.alphaValue = initAlpha - deltaAlpha

Full code should look like this:

    @IBAction func startAnimation(_ sender: NSButton) {
        let initAlpha = self.view1.alphaValue // Usually 1.0
        let endAlpha = CGFloat(0)
        let startTime = DispatchTime.now()  // Precisely when animation starts
        let fixedDuration = 5.0
        var elapsedTime : Double = 0.0

        NSAnimationContext.runAnimationGroup({ (context) in
            context.duration = fixedDuration // 5.0
            self.view1.animator().alphaValue = endAlpha // 0
        }) { // Completion
            let endTime = DispatchTime.now()
            elapsedTime = Double((endTime.uptimeNanoseconds - startTime.uptimeNanoseconds)) / 1_000_000_000 // Difference in seconds

            if elapsedTime >= fixedDuration {
                self.view1.alphaValue = initAlpha // return to initial value 1.0
            } else {        // Adjust proportionally
                let deltaAlpha = (initAlpha - endAlpha) * (elapsedTime / fixedDuration)
                self.view1.alphaValue = initAlpha - deltaAlpha
            }
        }
    }

Did you manage to stop the animation with this solution ?

How to stop an animation
 
 
Q