【问题标题】:CAEmitterLayer, eventually, has delay when adding EmitterCellsCAEmitterLayer 最终在添加 EmitterCells 时有延迟
【发布时间】:2019-12-12 20:10:11
【问题描述】:

我们已经看到的一个非常奇怪的问题(下面的 gifs),

  1. 我们有一个视图控制器,它有一个TeamBadgeView, 这是一个以CAEmitterCells 形式发出表情符号的按钮
  2. 点击此按钮可让用户在其屏幕上发送火焰表情符号
  3. 关闭呈现的视图控制器,重新呈现视图控制器,现在有延迟。我呈现/关闭视图控制器的次数越多,CAEmitterCell 就会变得越来越无响应
  4. 确认这不是泄漏问题,视图控制器和按钮正在正确释放
  5. 我尝试移动 CAEmitterLayerCAEmitterCell,在按钮中保留引用,并在本地声明,但类似的问题
  6. 也许最奇怪的是,如果我根本不按下按钮,只是多次呈现/关闭视图控制器,然后按下按钮,会有延迟。唯一没有延迟的情况是在第一次显示视图控制器时按下按钮
  7. 我已经确认按钮的action 被正确触发,每次我向按钮发送垃圾邮件。只是发射器单元没有渲染几秒钟。有些发射器单元根本不渲染

已经到了令人难以置信的地步,有人对这可能是什么有任何想法或线索吗?

ViewController的第一次介绍:

ViewController 第 5 次展示后(以相同的速度按下按钮):

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]
    }
}

【问题讨论】:

  • 你能发布一个演示项目吗?我很想试试这个。
  • 马特!很高兴见到你,我已经有好几年没有让你参与我的主题了 :) 让我现在创建一个项目
  • 在这里上传:github.com/MattyAyOh/FireDemo 这个项目其实透露了一些东西:火其实应该慢!看起来它一开始就不应该真正起作用。在我们的 ViewController 中,我们使用了 Hero 转换 (github.com/HeroTransitions/Hero),看起来这种转换是让火焰按预期工作的原因。删除过渡后,它又变慢了...
  • 那么听起来你不需要我了!
  • 嗨,所以我用您帖子中的代码创建了自己的项目(不是您的演示项目),我注意到为了显示许多火灾图像,我必须将新单元格附加到 @987654335 @ 而不是将其设置为 [cell] (如果 emitterCells 为 nil,那么我必须先将其初始化为一个空数组)。所以也许这就是它“慢”的原因?

标签: ios uikit core-animation caemitterlayer caemittercell


【解决方案1】:

而不是每次都设置emitterCells数组:

emitter.emitterCells = [cell]

...将新单元格附加到它。如果它为 nil,请确保将其初始化为一个空数组,否则附加将不起作用:

if emitter.emitterCells == nil {
    emitter.emitterCells = []
}

emitter.emitterCells?.append(cell)

【讨论】:

    【解决方案2】:

    感谢@TylerTheCompiler,我们能够解决这个问题,这真的很蹩脚。

    换行,而不是设置emitterCells,我们需要追加

        emitter.emitterCells = [cell]
    

    成为

        emitter.emitterCells?.append(cell)
    

    我们之所以没有注意到这一点,是因为它似乎与英雄转换有一种奇怪的互动。我们的 ViewController 是通过 Hero Transition 呈现的,出于某种原因,在第一次呈现时,emitterCells = [cell] 按预期工作......但是由于某种原因,对于随后的每个 Hero Transition 到 ViewController,cell 开始发射越来越慢直到它回到预期的缓慢状态。令人难以置信的奇怪,也许是英雄中的一个错误,但谁知道

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-29
      • 1970-01-01
      • 2017-01-27
      • 2018-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多