Search code examples
iosswiftcore-animationcaemitterlayer

Pausing and Resuming CAEmitterLayer Multiple of Times


I have a CAEmitterLayer instance that I want to pause and then resume multiple times.

I have found various ways to do this using two CAEmitterLayer extension functions:

public func pause() {
    speed = 0.0 // Freeze existing cells.
    timeOffset = convertTime(CACurrentMediaTime(), from: self)
    lifetime = 0.0 // Stop creating new cells.
}

and

public func resume() {
    speed = 1.0
    beginTime = convertTime(CACurrentMediaTime(), from: self) - timeOffset
    timeOffset = 0.0
    lifetime = 1.0
}

The first occasion of using emitterLayer.pause() and emitterLayer.resume() works perfectly.

However, from the second occasion onwards, whenever I use emitterLayer.pause(), the emitterCells jump slightly forward in time.

Can anybody out there help me resolve this jumping problem, please?


Solution

  • I needed to adjust the timeOffset in the pause() method. This is a working extension for pausing and resuming a CAEmitterLayer instance:

    extension CAEmitterLayer {
    
        /**
         Pauses a CAEmitterLayer.
         */
        public func pause() {
            speed = 0.0 // Freeze the CAEmitterCells.
            timeOffset = convertTime(CACurrentMediaTime(), from: self) - beginTime
            lifetime = 0.0 // Produce no new CAEmitterCells.
        }
    
        /**
         Resumes a paused CAEmitterLayer.
         */
        public func resume() {
            speed = 1.0 // Unfreeze the CAEmitterCells.
            beginTime = convertTime(CACurrentMediaTime(), from: self) - timeOffset
            timeOffset = 0.0
            lifetime = 1.0 // Produce CAEmitterCells at previous rate.
        }
    
    }
    

    Use as:

    var emitterLayer = CAEmitterLayer()
    /// Configure as required
    
    emitterLayer.pause()
    emitterLayer.resume()