Skip to content

Instantly share code, notes, and snippets.

@nazywamsiepawel
Created January 4, 2016 22:01
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nazywamsiepawel/e462193f299187d0fc8e to your computer and use it in GitHub Desktop.
Save nazywamsiepawel/e462193f299187d0fc8e to your computer and use it in GitHub Desktop.
Pause / Resume CABasicAnimation with Swift
func pauseAnimation(){
var pausedTime = layer.convertTime(CACurrentMediaTime(), fromLayer: nil)
layer.speed = 0.0
layer.timeOffset = pausedTime
}
func resumeAnimation(){
var pausedTime = layer.timeOffset
layer.speed = 1.0
layer.timeOffset = 0.0
layer.beginTime = 0.0
let timeSincePause = layer.convertTime(CACurrentMediaTime(), fromLayer: nil) - pausedTime
layer.beginTime = timeSincePause
}
@JoeySlomowitz
Copy link

This was very helpful for me. Thank you!

@Rotemy
Copy link

Rotemy commented Jul 23, 2018

Works perfectly!

@everlof
Copy link

everlof commented Nov 14, 2018

Works great when speed is 1.0, but not when it's for example 0.1 :o

@robertmryan
Copy link

The above is an adaptation from Core Animation Programming Guide: Pausing and Resuming Animations. But convertTime(_:fromLayer:) has been renamed to convertTime(_:from:). And we can use let. Thus:

func pauseAnimation() {
    let pausedTime = layer.convertTime(CACurrentMediaTime(), from: nil)
    layer.speed = 0
    layer.timeOffset = pausedTime
}

func resumeAnimation() {
    let pausedTime = layer.timeOffset
    layer.speed = 1
    layer.timeOffset = 0
    layer.beginTime = 0
    let timeSincePause = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
    layer.beginTime = timeSincePause
}

@rijieli
Copy link

rijieli commented Apr 22, 2022

Works perfectly on iOS 15.4, and my code about animation goes:

static let animationKey = "ProgressLayerGrowAnimation"

func progressAnimation() {
    if let CAKeys = progressLayer.animationKeys(), CAKeys.contains(Self.animationKey) {
        let pausedTime = progressLayer.timeOffset
        progressLayer.speed = 1.0
        progressLayer.timeOffset = 0.0
        progressLayer.beginTime = 0.0
        let timeSincePause = progressLayer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
        progressLayer.beginTime = timeSincePause
        return
    } 
      
    let circularProgressAnimation = <#whatever animation#>
    progressLayer.add(circularProgressAnimation, forKey: Self.animationKey)
}

func resetAnimation() {
    progressLayer.removeAnimation(forKey: Self.animationKey)
}

func pauseAnimation() {
    let pausedTime = progressLayer.convertTime(CACurrentMediaTime(), from: nil)
    progressLayer.speed = 0.0
    progressLayer.timeOffset = pausedTime
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment