Today we'll be taking a look at another often overlooked, yet quite powerful tool in Core Graphics: CAEmitterLayer. It can help us create all sorts of interesting particle effects. We're going to use it to make some chocolate rain. Let's do it!

We'll start by creating a new emitter layer. (We'll need to do all of this inside some view we want to rain chocolate down upon).

var emitter = CAEmitterLayer()

Next, we'll configure its size, position, and shape so it looks essentially like a "rain bar" at the top of our view:

emitter.emitterPosition = CGPoint(x: frame.size.width / 2.0, y: 0)
emitter.emitterShape = kCAEmitterLayerLine
emitter.emitterSize = CGSize(width: frame.size.width, height: 1)

For the shape, we could have chosen a point, circle, rectangle, sphere, etc. We chose a line because we want the generated particles to "rain down" vertically.

emitter.emitterCells = (0..<5).map({ _ in
  let intensity = Float(0.5)

  let cell = CAEmitterCell()

  cell.birthRate = 6.0 * intensity
  cell.lifetime = 14.0 * intensity
  cell.lifetimeRange = 0
  cell.velocity = CGFloat(350.0 * intensity)
  cell.velocityRange = CGFloat(80.0 * intensity)
  cell.emissionLongitude = CGFloat(M_PI)
  cell.emissionRange = CGFloat(M_PI_4)
  cell.spin = CGFloat(3.5 * intensity)
  cell.spinRange = CGFloat(4.0 * intensity)
  cell.scaleRange = CGFloat(intensity)
  cell.scaleSpeed = CGFloat(-0.1 * intensity)
  cell.contents = UIImage(named: "bite")!.cgImage

  return cell
})

Finally, we'll do the bulk of the work by adding 5 CAEmitterCells to our emitter layer. (Hint: Want more particles? Add more cells.)

These cells are where we configure how particles get genreated and how they behave once they are on screen.

There's ton of examples of different techniques online and the docs have more indepth info on each property

Don't be scared by all the magic numbers. Entire books have been written about how to generate certain particles effects. Things can get quite complicated.

We'll finish up by adding our emitter layer as a sublayer of the layer of the view we're working in:

layer.addSublayer(emitter)

Success!

Looking for a library that encapsulates this technique into a handy reusable view? Check out SAConfettiView by Sudeep Agarwal