Written by Alex Gibson, on May 11, 2017


The power of the CALayer class is amazing. Recently I was looking at adding some stars to a press of a UIButton.  I realized quickly how easy it was to do.

 

Download the starter project and let’s get this done.

Open up the ViewController file and in the function buttonDidPressDown we are going to add the code for our animation and below that we will need one helper method.  To understand how to use CAEmitterLayer you can view the documentation at https://developer.apple.com/reference/quartzcore/caemitterlayer.  Quickly glancing through the docs you can see that the CAEmitterLayer needs and array of CAEmitterCells. The cells will be the particles that animate around and the cells are where we will add the animation properties.  If you look through the docs on the CAEmitterCell you will see that they have quite a lot of animatable properties.  Let’s define that helper function that we talked about that will be a factory method to create some cells.


func makeEmitterCell() -> CAEmitterCell {
        let cell = CAEmitterCell()
        let image = UIImage(named: "starsmall")
        cell.contents = image?.cgImage
        cell.birthRate = 20
        cell.lifetime = 0.8
        cell.lifetimeRange = 0.2
        cell.velocity = 100
        cell.velocityRange = 20
        cell.emissionRange = CGFloat.pi * 2
        cell.spin = 2
        cell.spinRange = 5
        cell.scaleRange = 0.7
        cell.scaleSpeed = -0.05
        cell.alphaSpeed = -0.5
        cell.alphaRange = 1
        cell.alphaSpeed = -1
        cell.scale = 1.0
        cell.scaleSpeed = 0.5
        cell.color = UIColor.yellow.cgColor
        
        return cell
    }

This is really not as complex as it might look it you read through all the properties.  The first three lines create the cell and set a small star to the cell contents.  The rest of the lines create a birthrate(new cells per second), a lifetime, variance, velocity, spin, scale, color, and alpha.  The range properties allows each to vary.  To create the animation all we need to do is create the CAEmitterLayer and add that to the layer of the target, the button in our case.  Go to buttonDidPressDown


@IBAction func buttonDidPressDown(_ sender: UIButton) {

        let particleEmitter = CAEmitterLayer()
        particleEmitter.emitterPosition = CGPoint(x: sender.bounds.midX, y: sender.bounds.midY)
        particleEmitter.emitterShape = kCAEmitterLayerPoint
        particleEmitter.emitterSize = sender.bounds.size
        let cell = makeEmitterCell()
        particleEmitter.emitterCells = [cell]
        sender.layer.addSublayer(particleEmitter)
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) {
            particleEmitter.removeFromSuperlayer()
        }
        
    }

So in the pressDown we create the CAEmitterLayer and set the position inside the UIButton to the center.  We then set the size.  We call our cell factory and get a cell.  Then we add the CAEmitterLayer to the button’s sublayer.  It will immediately start animating.  The next bit of code simply removes the particleEmitter layer after 0.8 seconds have occurred.  Run the project and enjoy.