risa8
risa8

Reputation: 253

Stop function after secods

I have setup and position the CAEmitterLayer. It shows images coming from the emitter.

The code works very well, but I have one problem. I would like to stop snowDribbbleBalls() function after 5 seconds it is called. I appreciate any help lead me to solve the problem.

(Instead of removing sublayers, I would like to simply stop function.)

//real code
class CompletedViewController: UIViewController {

                               self.snowDribbbleBalls()
            DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(5)) { [weak self] in
                cell.birthRate = 0
                cell2.birthRate = 0
                cell3.birthRate = 0
                cell4.birthRate = 0

            }


}

func snowDribbbleBalls() {

        let emitter = Emitter.get(with: #imageLiteral(resourceName: "ichi"))
        emitter.emitterPosition = CGPoint(x: view.frame.width / 2, y: 0)
        emitter.emitterSize = CGSize(width: view.frame.width, height: 2)
        self.view.layer.addSublayer(emitter)

        let emitter2 = Emitter.get(with: #imageLiteral(resourceName: "ni"))
        emitter2.emitterPosition = CGPoint(x: view.frame.width / 6, y: 0)
        emitter2.emitterSize = CGSize(width: view.frame.width, height: 2)
        self.view.layer.addSublayer(emitter2)

        let emitter3 = Emitter.get(with: #imageLiteral(resourceName: "san"))
        emitter3.emitterPosition = CGPoint(x: view.frame.width / 1, y: 0)
        emitter3.emitterSize = CGSize(width: view.frame.width, height: 2)
        self.view.layer.addSublayer(emitter3)

        let emitter4 = Emitter.get(with: #imageLiteral(resourceName: "yon"))
        emitter4.emitterPosition = CGPoint(x: view.frame.width / 3.5, y: 0)
        emitter4.emitterSize = CGSize(width: view.frame.width, height: 2)
        self.view.layer.addSublayer(emitter3)
    }



class Emitter {
    static func get(with image: UIImage) -> CAEmitterLayer {
        let emitter = CAEmitterLayer()
        emitter.emitterShape = kCAEmitterLayerLine
        emitter.emitterCells = generateEmitterCells(with: image)

        let emitter2 = CAEmitterLayer()
        emitter2.emitterShape = kCAEmitterLayerLine
        emitter2.emitterCells = generateEmitterCells(with: image)

        let emitter3 = CAEmitterLayer()
        emitter3.emitterShape = kCAEmitterLayerLine
        emitter3.emitterCells = generateEmitterCells(with: image)

        let emitter4 = CAEmitterLayer()
        emitter4.emitterShape = kCAEmitterLayerLine
        emitter4.emitterCells = generateEmitterCells(with: image)

        return emitter
    }

    static func generateEmitterCells(with image: UIImage) -> [CAEmitterCell] {
        var cells = [CAEmitterCell]()

        let cell = CAEmitterCell()
        cell.contents = image.cgImage
        cell.birthRate = 30
        cell.lifetime = 50
        cell.velocity = CGFloat(300)
        cell.emissionLongitude = (180 * (.pi/180))
        cell.emissionRange = (14 * (.pi/180))
        cell.scale = 0.25
        cell.scaleRange = 0.3
        ////
        let cell2 = CAEmitterCell()
        cell2.contents = image.cgImage
        cell2.birthRate = 26
        cell2.lifetime = 50
        cell2.velocity = CGFloat(160)
        cell2.emissionLongitude = (180 * (.pi/180))
        cell2.emissionRange = (12 * (.pi/180))
        cell2.scale = 0.25
        cell2.scaleRange = 0.2
        ////
        let cell3 = CAEmitterCell()
        cell3.contents = image.cgImage
        cell3.birthRate = 20
        cell3.lifetime = 50
        cell3.velocity = CGFloat(160)
        cell3.emissionLongitude = (180 * (.pi/180))
        cell3.emissionRange = (16 * (.pi/180))
        cell3.scale = 0.25
        cell3.scaleRange = 0.2
        ////
        let cell4 = CAEmitterCell()
        cell4.contents = image.cgImage
        cell4.birthRate = 27
        cell4.lifetime = 20
        cell4.velocity = CGFloat(260)
        cell4.emissionLongitude = (180 * (.pi/180))
        cell4.emissionRange = (10 * (.pi/180))
        cell4.scale = 0.25
        cell4.scaleRange = 0.2

        cells.append(cell)

        return cells

    }

}

Upvotes: 0

Views: 397

Answers (1)

Alladinian
Alladinian

Reputation: 35646

Just to make things clear... The function doesn't 'run' while the layer is emitting, so the real question is "How to stop the emitter ?" and the answer to this is by setting the birthRate of the emitter layer to zero.

So just hold a reference (since you don't want to be removed) and set the birthRate to zero after 5 seconds...

Something like:

DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(5)) { [weak self] in
    // self.emitter is declared as
    // var emitter: CAEmitterLayer!
    // and set on `emitter = Emitter.get(with: #imageLiteral(resourceName: "ichi"))`
    self?.emitter.birthRate = 0
}

Upvotes: 2

Related Questions