A very bizarre issue we've been seeing (gifs below),
- We have a presented View Controller that has a
TeamBadgeView
, which is a button that emits emoji asCAEmitterCells
- Tapping this button lets users spam a fire emoji on their screen
- Dismissing the presented view controller, and re-present the view controller, and now there is a delay. The more times I present/dismiss the view controller, the
CAEmitterCell
becomes more and more unresponsive - Confirmed that this is not a leak issue, the view controller and button are being properly deallocated
- I have tried moving the
CAEmitterLayer
andCAEmitterCell
around, holding a reference in the button, and declaring locally, but similar issues - Perhaps most bizarre, if I do not press the button at all, and simply present/dismiss the viewcontroller many times, and then press the button, there is a delay. The only time there isn't a delay is pressing the button on the first time the View Controller is presented
- I have confirmed that the button's
action
is being fired correct, everytime I spam the button. It's just that the emitter cell is not rendering for a few seconds. And some of the emitter cells just don't render at all
It's gotten to the mind-boggling point, does anybody have any ideas or leads on what this could be?
First presentation of ViewController:
After 5th presentation of ViewController (Pressing button at same rate):
ViewController code:
let teamBadgeView = TeamBadgeView.fromNib()
teamBadgeView.configure()
Button code:
class TeamBadgeView: UIView {
let emitter = CAEmitterLayer()
let fireSize = CGSize(width: 16, height: 18)
let fireScale: CGFloat = 0.8
func configure() {
emitter.seed = UInt32(CACurrentMediaTime())
emitter.emitterPosition = CGPoint(x: bounds.midX, y: 0)
emitter.emitterShape = CAEmitterLayerEmitterShape.line
emitter.emitterSize = fireSize
emitter.renderMode = CAEmitterLayerRenderMode.additive
layer.addSublayer(emitter)
}
@IBAction func tapAction(_ sender: Any) {
emitFire()
}
private func emitFire() {
let cell = CAEmitterCell()
let beginTime = CACurrentMediaTime()
cell.birthRate = 1
cell.beginTime = beginTime
cell.duration = 1
cell.lifetime = 1
cell.velocity = 250
cell.velocityRange = 50
cell.yAcceleration = 100
cell.alphaSpeed = -1.5
cell.scale = fireScale
cell.emissionRange = .pi/8
cell.contents = NSAttributedString(string: "").toImage(size: fireSize)?.cgImage
emitter.emitterCells = [cell]
}
}
Instead of setting the
emitterCells
array every time:...append the new cell to it. Make sure to initialize it to an empty array if it's nil though, or else the append will not work: