2

我正在尝试使用CAEmitterLayer和几个CAEmitterCell. 这应该在用户看到视图后的短暂延迟后发生。我开始我的动画viewDidAppear

粒子动画本身可以正常工作,但正如在这个问题中,CAEmitterLayer 的初始粒子不会从emitterPosition 开始,除非我将emitterLayer.beginTime = CACurrentMediaTime()动画设置为已经运行了一段时间的用户。

现在要真正实现爆炸,我必须在某个时候停止发射粒子。我尝试使用此代码来设置CABasicAnimation一段时间后会停止发射器:

// emitter layer is reused (remove all animations, remove all cells, remove from superlayer)
... // emitter layer setup in a function "explode" which is called from viewDidAppear
emitterLayer.beginTime = CACurrentMediaTime()

let birthRateAnimation = CABasicAnimation(keyPath: "birthRate")
birthRateAnimation.toValue = 0
birthRateAnimation.timingFunction = CAMediaTimingFunction.init(name:kCAMediaTimingFunctionEaseOut)
birthRateAnimation.beginTime = CACurrentMediaTime() + 1
birthRateAnimation.duration = 5
birthRateAnimation.delegate = self // (self is view controller)
birthRateAnimation.setValue("expl", forKey: "animName")

emitterLayer.add(birthRateAnimation, forKey: "birthRateAnimation")
self.view.layer.addSublayer(emitterLayer)

所以现在这个代码birthRateAnimation实际上并没有被触发。我已经登录animationDidStop并且animationDidStart不打印任何内容。

现在,如果我explode在按钮点击时调用函数,我根本看不到粒子动画,但在日志中我看到“动画开始”/“动画停止”消息。

知道为什么吗?

4

2 回答 2

2

我发现了两个使动画无法正常工作的问题。

  1. 动画开启birthRate,但CAEmitterLayer没有birthRate属性;CAEmitterCell确实如此。给你CAEmitterCell的名字并更改CABasicAnimation(keyPath: "birthRate")CABasicAnimation(keyPath: "emitterCells.cellName.birthRate")
  2. 将 beginTime 设置为CACurrentMediaTime() + 1.0不符合您的要求,因为发射器层有自己的时间刻度。将其更改为emitterLayer.convertTime(CACurrentMediaTime(), from: nil) + 1.0您想要的。
于 2017-08-08T22:41:39.610 回答
1

派对迟到了,但我遇到了同样的事情,解决方案是将beginTime发射器设置为CACurrentMediaTime(),例如:

let emitter = makeAwesomeEmitter()
emitter.beginTime = CACurrentMediaTime()

let emitterAnimation = makeAwesomeEmitterBirthRateAnimation()
emitterAnimation.beginTime = 1.0 // 1 sec delay
emitter.add(emitterAnimation, forKey: nil)

myView.layer.addSublayer(emitter)

基本原理是发射器预先生成粒子以模仿它已经运行了一段时间。另请参阅this SO question,它让我找到了解决方案。

于 2018-08-04T16:58:32.870 回答