Swift - CAEmitterCell、CAEmitterLayer和微信表情雨

这篇教程将一起学习使用CAEmitterCellCAEmitterLayer,最后做出一个仿微信表情雨的效果。

开发环境:Swift 3.0 + Xcode 8.2

先看最终效果:


仿微信表情雨.gif

CAEmitterCell定义了一种粒子的原型,然后通过CAEmitterLayer对象发射这些粒子。一种粒子原型包括了设定其方向和粒子发射属性。粒子原型本身还可以包含子粒子(sub-cells),以实现其本身再将子粒子发射出去的效果。在效果图中,每一个便是由CAEmitterCell定义的。我们需要设定的值看代码(当然还有别的值,代码中给出的只是一小部分)。

CAEmitterLayerCALayer的子类,定义了发射粒子的动画图层。粒子是被渲染在此图层上的。如果说CAEmitterCell是子弹,那CAEmitterLayer就是那把枪了。

代码比较简单,直接上。

let cell = CAEmitterCell()
cell.name = "laughing"          // 后面的KVC会用到
cell.contents = "".cgImage    // 图层内容
cell.birthRate = 10.0            // 粒子的每秒的产出速率
cell.lifetime = 10.0            // 显示时长
cell.velocity = -80             // 速度,向下为负
cell.velocityRange = -40        // 速度变化区间
cell.yAcceleration = 45         // y轴上的加速度
cell.emissionRange = .pi / 8    // 发射角度变化区间

let emitterLayer = CAEmitterLayer()
emitterLayer.frame = CGRect(x: 0, y: 0, width: view.bounds.size.width, height: 20)
emitterLayer.emitterSize = CGSize(width: view.bounds.size.width, height: 0)
emitterLayer.emitterPosition = CGPoint(x: view.bounds.size.width / 2, y: -40)
emitterLayer.emitterMode = kCAEmitterLayerOutline   // 发射样式,这里指围绕发射器的外轮廓发射
emitterLayer.emitterShape = kCAEmitterLayerLine     // 发射器的形状,可以是线形、圆形、方形等
emitterLayer.emitterCells = [cell]                  // 传入粒子对c象
view.layer.addSublayer(emitterLayer)

如何暂停呢?直接cell.birthRate = 0是停不下来的,我们需要用KVC:emitterLayer.setValue(0.0, forKeyPath: "emitterCells.laughing.birthRate")

CALayercontent是一个Any?,实际上要传入的是一个CGImage对象。为了使emoji表情也能变成一个CGImage,我稍微给String加了个extension。正好复习一下UIGraphicsBeginImageContextWithOptions那几个API。

extension String {
    // 将字符串以CGImage显示
    var cgImage: CGImage? {
        let textAttri: [String: Any]? = [NSFontAttributeName: UIFont.systemFont(ofSize: 16)]
        
        UIGraphicsBeginImageContextWithOptions(self.size(attributes: textAttri), false, 0)
        defer { UIGraphicsEndImageContext() }
        
        self.draw(at: .zero, withAttributes: textAttri)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        return image?.cgImage
    }
}

大功告成。附上源码:https://github.com/Hesse-Huang/CAEmitterCellLearning
最后有个小问题,就是每次点击Button时有几个粒子直接出现,而不是在屏幕上边缘落下。如果知道如何解决的同学请留言评论哦,谢谢~

你可能感兴趣的:(Swift - CAEmitterCell、CAEmitterLayer和微信表情雨)