0

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

    }

}
risa8
  • 243
  • 1
  • 11
  • DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: { self.snowDribbbleBalls() }) if you want to remove this than use removefrom subview – BHAVIK PANCHAL Jul 17 '17 at 06:37
  • `snowDribbbleBalls()` will run just a few microseconds, no seconds. In fact do you want stop an animation? – clemens Jul 17 '17 at 06:37
  • @ macmoonshine yes I would like to stop animation! – risa8 Jul 17 '17 at 06:42
  • You can use this answer https://stackoverflow.com/a/25120393/2000162 Run with a delay and cancel whenever you need it – TomCobo Jul 17 '17 at 06:55

1 Answers1

2

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
}
Alladinian
  • 32,266
  • 4
  • 79
  • 85
  • @risa8 Can you please edit your question and share your code? Because I _did_ try my answer before posting and is working fine... – Alladinian Jul 20 '17 at 09:57
  • Ok give me a second. The error is "Value of CompleteViewController has no member cell2." – risa8 Jul 20 '17 at 09:59
  • ... so what is `cell2`? It seems that this problem is unrelated to the specific question... – Alladinian Jul 20 '17 at 10:02
  • Sorry mistype it is cell – risa8 Jul 20 '17 at 10:03
  • I would gladly help you with that, but you have to post some _real_ code in your question. Just hit `Edit` and include the code as it is now if possible – Alladinian Jul 20 '17 at 10:07
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/149695/discussion-between-alladinian-and-risa8). – Alladinian Jul 20 '17 at 10:09