当CAEmitterLayer结束CAEmitter单元的生命周期时,如何移除CAEmitterLayer – 而不是直到从超级层中移除CAEmitterLayer

我使用generics代码(来自iOS Fireworks演示)稍微改变了一下。 我有以下在UIView的子类。 我想要的是让烟花出现在用户触摸的地方(不难),并在CAEmitterLayer / CAEmitterCells的“生命周期”长度上播放。 相反,这是立即开始,当我把它添加到addSublayer – 就像我相信它的意思。 不过,我想用稍微不同的方式来使用它。 有没有办法,我可以改变这个,所以有一个完成块(removeFromSuperlayer)或类似的东西的CATransaction? 任何想法都欢迎。

#import "FireworksView.h" @implementation FireworksView - (void)launchFirework{ //Load the spark image for the particle CAEmitterLayer *mortor = [CAEmitterLayer layer]; mortor.emitterPosition = CGPointMake(self.bounds.size.width/2, self.bounds.size.height*(.75)); mortor.renderMode = kCAEmitterLayerAdditive; //Invisible particle representing the rocket before the explosion CAEmitterCell *rocket = [CAEmitterCell emitterCell]; rocket.emissionLongitude = -M_PI / 2; rocket.emissionLatitude = 0; rocket.lifetime = 1.6; rocket.birthRate = 1; rocket.velocity = 400; rocket.velocityRange = 100; rocket.yAcceleration = 250; rocket.emissionRange = M_PI / 4; rocket.color = CGColorCreateCopy([UIColor colorWithRed:.5 green:.5 blue:.5 alpha:.5].CGColor); rocket.redRange = 0.5; rocket.greenRange = 0.5; rocket.blueRange = 0.5; //Name the cell so that it can be animated later using keypath [rocket setName:@"rocket"]; //Flare particles emitted from the rocket as it flys CAEmitterCell *flare = [CAEmitterCell emitterCell]; flare.contents = (id)[UIImage imageNamed:@"tspark.png"].CGImage; flare.emissionLongitude = (4 * M_PI) / 2; flare.scale = 0.4; flare.velocity = 100; flare.birthRate = 45; flare.lifetime = 1.5; flare.yAcceleration = 350; flare.emissionRange = M_PI / 7; flare.alphaSpeed = -0.7; flare.scaleSpeed = -0.1; flare.scaleRange = 0.1; flare.beginTime = 0.01; flare.duration = 0.7; //The particles that make up the explosion CAEmitterCell *firework = [CAEmitterCell emitterCell]; firework.contents = (id)[UIImage imageNamed:@"tspark.png"].CGImage; firework.birthRate = 9999; firework.scale = 0.6; firework.velocity = 130; firework.lifetime = 2; firework.alphaSpeed = -0.2; firework.yAcceleration = 80; firework.beginTime = 1.5; firework.duration = 0.1; firework.emissionRange = 2 * M_PI; firework.scaleSpeed = -0.1; firework.spin = 2; //Name the cell so that it can be animated later using keypath [firework setName:@"firework"]; //preSpark is an invisible particle used to later emit the spark CAEmitterCell *preSpark = [CAEmitterCell emitterCell]; preSpark.birthRate = 80; preSpark.velocity = firework.velocity * 0.70; preSpark.lifetime = 1.7; preSpark.yAcceleration = firework.yAcceleration * 0.85; preSpark.beginTime = firework.beginTime - 0.2; preSpark.emissionRange = firework.emissionRange; preSpark.greenSpeed = 100; preSpark.blueSpeed = 100; preSpark.redSpeed = 100; //Name the cell so that it can be animated later using keypath [preSpark setName:@"preSpark"]; //The 'sparkle' at the end of a firework CAEmitterCell *spark = [CAEmitterCell emitterCell]; spark.contents = (id)[UIImage imageNamed:@"tspark.png"].CGImage; spark.lifetime = 0.05; spark.yAcceleration = 250; spark.beginTime = 0.8; spark.scale = 0.4; spark.birthRate = 10; preSpark.emitterCells = [NSArray arrayWithObjects:spark, nil]; rocket.emitterCells = [NSArray arrayWithObjects:flare, firework, preSpark, nil]; mortor.emitterCells = [NSArray arrayWithObjects:rocket, nil]; [self.layer addSublayer:mortor]; } 

答案是,使用CAEmitter,没有方法 – 委托等 – 停止发射器,当它结束的周期。 你可以做的唯一的事情就是当你认为它应该被删除时,优雅地从图层中删除它。

好的,所以我可以通过创build一个带有发射器的委托的animation来达到此目的。 在animationDidStop我做了一个for循环,通过我的视图层次结构,并寻找发射器,并将其删除。 它是越野车,我仍然想要一个真正的解决scheme,但现在工作。

 for (CALayer *layer in _plusButton.layer.sublayers) { if (layer.class == [CAEmitterLayer class]) { [layer removeFromSuperlayer]; } }