Pausing and Resuming CAEmitterLayer Multiple of Times

263 Views Asked by At

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?

1

There are 1 best solutions below

0
On BEST ANSWER

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