CAEmitterLayer烟花效果运行数次后停止显示的Objective-C问题
解决CAEmitterLayer烟花多次触发失效的问题
核心问题分析
你的代码中,Parent 发射器单元格的 beginTime 在 viewDidLoad 阶段就被固定为当时的媒体时间(CACurrentMediaTime())。多次触发时,当前时间早已超过这个固定的 beginTime 加上单元格生命周期(2.5秒)的范围,导致新的粒子无法被正常发射。
具体修复方案
- 缓存Parent单元格引用
在类的接口部分添加属性,直接持有Parent单元格的引用,避免每次用KVC路径查找的不可靠性:
@interface YourViewController () @property (nonatomic, strong) CAEmitterLayer *emitterLayer; @property (nonatomic, strong) CAEmitterCell *parentEmitterCell; @end
- 初始化时绑定引用
修改setupFireWorkEmitterCells方法,将创建的Parent单元格赋值给属性,并移除初始的固定beginTime设置:
-(void) setupFireWorkEmitterCells{ NSLog(@"setupFirework cellls"); // 创建Parent单元格 CAEmitterCell *cell1 = [CAEmitterCell emitterCell]; cell1.name = @"Parent"; cell1.birthRate = 0.0; cell1.lifetime = 2.5; // 移除原有固定的beginTime设置,改为触发时动态赋值 // cell1.beginTime = CACurrentMediaTime(); // ... 其他原有配置代码保持不变 // 绑定到属性 self.parentEmitterCell = cell1; // ... 创建子单元格的代码保持不变 cell1.emitterCells = [NSArray arrayWithObjects:subcell1_1, subcell1_2, nil]; self.emitterLayer.emitterCells = [NSArray arrayWithObject:self.parentEmitterCell]; }
- 触发时重置beginTime并设置birthRate
修改StartFW方法,每次触发时将Parent单元格的beginTime重置为当前媒体时间,确保粒子从当前时间开始生成:
-(IBAction)StartFW { // 重置beginTime为当前时间,保证粒子生命周期从现在开始计算 self.parentEmitterCell.beginTime = CACurrentMediaTime(); // 直接设置birthRate,替代KVC方式更稳定 self.parentEmitterCell.birthRate = 1; }
- 优化停止逻辑
同样用直接引用的方式停止粒子发射:
-(IBAction)StopFW { self.parentEmitterCell.birthRate = 0; }
额外排查点
- 检查
subcell1_1和subcell1_2的beginTime:它们是相对于Parent单元格生命周期的偏移量(0.01和1.6秒),这个配置是合理的,无需修改。 - 如果问题仍存在,可以尝试在停止时调用
[self.emitterLayer removeAllAnimations],但通常重置birthRate和beginTime已经足够解决问题。
内容的提问来源于stack exchange,提问作者jsdigital
相关产品推荐
相关产品推荐

