I want to run CAEmitterLayer only once, I was thinking of stopping birthRate but I can't do it. What I want is for it to run only once when tapping on the screen. I've been trying with delegates but I can't get it to work. And could you please tell me if my code is efficient.
import UIKit
import PlaygroundSupport
class Emitter {
static func get(with image: UIImage) -> CAEmitterLayer {
let emitter = CAEmitterLayer()
emitter.emitterShape = kCAEmitterLayerLine
emitter.emitterCells = generateEmitterCells(image: image)
print("emit")
emitter.setValue(0.0, forKey: "em")
return emitter
}
static func generateEmitterCells(image: UIImage) -> [CAEmitterCell] {
var cells = [CAEmitterCell]()
let cell = CAEmitterCell()
cell.contents = image.cgImage
cell.birthRate = 0.1
cell.lifetime = 20
cell.velocity = 250
cell.emissionRange = (10 * (.pi/180))
cell.scale = 0.9
cell.scaleRange = 0.3
cell.velocityRange = 100
cells.append(cell)
print("cells")
return cells
}
}
class ViewController : UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
let view2 = UIView(frame: self.view.frame)
self.view.frame = CGRect(x: 0, y: 0, width: 320, height: 580)
super.view.backgroundColor = UIColor.white
self.view.addSubview(view2)
}
@objc func handleTap() {
rain()
}
func rain() {
let emitter = Emitter.get(with: UIImage(named: "Group 1493")!)
emitter.emitterPosition = CGPoint(x: view.frame.width / 2, y: view.frame.height + 25)
emitter.emitterSize = CGSize(width: view.frame.width, height: 2)
self.view.layer.addSublayer(emitter)
}
}
let controller = ViewController()
PlaygroundPage.current.liveView = controller.view
You could set lifetime propertie to 0 after first splash
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
emitter.lifetime = 0
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With