CAEmitterLayer 最终在添加 EmitterCells 时有延迟
CAEmitterLayer, eventually, has delay when adding EmitterCells
我们一直看到的一个非常奇怪的问题(下面的 gif),
- 我们有一个视图控制器,它有一个
TeamBadgeView
,
这是一个发出表情符号的按钮 CAEmitterCells
- 点击此按钮可让用户在屏幕上发送垃圾表情符号
- 正在关闭呈现的视图控制器,并重新呈现视图控制器,现在有延迟。我 present/dismiss 视图控制器的次数越多,
CAEmitterCell
变得越来越无响应
- 已确认这不是泄漏问题,正在正确释放视图控制器和按钮
- 我试过移动
CAEmitterLayer
和 CAEmitterCell
,在按钮中保留引用,并在本地声明,但类似的问题
- 也许最奇怪的是,如果我根本不按按钮,只是 present/dismiss 多次 viewcontroller,然后再按按钮,就会出现延迟。唯一没有延迟的是在第一次显示视图控制器时按下按钮
- 我已经确认按钮的
action
被正确触发,每次我向按钮发送垃圾邮件。只是发射器单元有几秒钟没有渲染。还有一些发射器单元根本不渲染
已经到了令人难以置信的地步,有人对这可能是什么有任何想法或线索吗?
ViewController 的首次展示:
第 5 次呈现 ViewController 后(以相同的速度按下按钮):
ViewController代码:
let teamBadgeView = TeamBadgeView.fromNib()
teamBadgeView.configure()
按钮代码:
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]
}
}
而不是每次都设置emitterCells
数组:
emitter.emitterCells = [cell]
...将新单元格附加到它。如果它为 nil,请确保将其初始化为空数组,否则追加将不起作用:
if emitter.emitterCells == nil {
emitter.emitterCells = []
}
emitter.emitterCells?.append(cell)
多亏了@TylerTheCompiler,我们才能够解决这个问题,这真的很蹩脚。
一行更改,而不是设置 emitterCells
,我们需要附加
emitter.emitterCells = [cell]
成为
emitter.emitterCells?.append(cell)
我们之所以没有注意到这一点,是因为它似乎与英雄转换有一种奇怪的互动。我们的 ViewController 是通过 Hero Transition 呈现的,由于某种原因,它第一次呈现时,emitterCells = [cell]
会按预期工作......但由于某种原因,对于每个后续的 Hero Transition 到 ViewController,细胞开始发射越来越慢,直到它回到预期的缓慢状态。莫名其妙,可能是Hero的bug,谁知道呢
我们一直看到的一个非常奇怪的问题(下面的 gif),
- 我们有一个视图控制器,它有一个
TeamBadgeView
, 这是一个发出表情符号的按钮CAEmitterCells
- 点击此按钮可让用户在屏幕上发送垃圾表情符号
- 正在关闭呈现的视图控制器,并重新呈现视图控制器,现在有延迟。我 present/dismiss 视图控制器的次数越多,
CAEmitterCell
变得越来越无响应 - 已确认这不是泄漏问题,正在正确释放视图控制器和按钮
- 我试过移动
CAEmitterLayer
和CAEmitterCell
,在按钮中保留引用,并在本地声明,但类似的问题 - 也许最奇怪的是,如果我根本不按按钮,只是 present/dismiss 多次 viewcontroller,然后再按按钮,就会出现延迟。唯一没有延迟的是在第一次显示视图控制器时按下按钮
- 我已经确认按钮的
action
被正确触发,每次我向按钮发送垃圾邮件。只是发射器单元有几秒钟没有渲染。还有一些发射器单元根本不渲染
已经到了令人难以置信的地步,有人对这可能是什么有任何想法或线索吗?
ViewController 的首次展示:
第 5 次呈现 ViewController 后(以相同的速度按下按钮):
ViewController代码:
let teamBadgeView = TeamBadgeView.fromNib()
teamBadgeView.configure()
按钮代码:
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]
}
}
而不是每次都设置emitterCells
数组:
emitter.emitterCells = [cell]
...将新单元格附加到它。如果它为 nil,请确保将其初始化为空数组,否则追加将不起作用:
if emitter.emitterCells == nil {
emitter.emitterCells = []
}
emitter.emitterCells?.append(cell)
多亏了@TylerTheCompiler,我们才能够解决这个问题,这真的很蹩脚。
一行更改,而不是设置 emitterCells
,我们需要附加
emitter.emitterCells = [cell]
成为
emitter.emitterCells?.append(cell)
我们之所以没有注意到这一点,是因为它似乎与英雄转换有一种奇怪的互动。我们的 ViewController 是通过 Hero Transition 呈现的,由于某种原因,它第一次呈现时,emitterCells = [cell]
会按预期工作......但由于某种原因,对于每个后续的 Hero Transition 到 ViewController,细胞开始发射越来越慢,直到它回到预期的缓慢状态。莫名其妙,可能是Hero的bug,谁知道呢