You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CAEmitterLayer烟花效果运行数次后停止显示的Objective-C问题

解决CAEmitterLayer烟花多次触发失效的问题

核心问题分析

你的代码中,Parent 发射器单元格的 beginTime 在 viewDidLoad 阶段就被固定为当时的媒体时间(CACurrentMediaTime())。多次触发时,当前时间早已超过这个固定的 beginTime 加上单元格生命周期(2.5秒)的范围,导致新的粒子无法被正常发射。

具体修复方案

  1. 缓存Parent单元格引用
    在类的接口部分添加属性,直接持有Parent单元格的引用,避免每次用KVC路径查找的不可靠性:
@interface YourViewController ()
@property (nonatomic, strong) CAEmitterLayer *emitterLayer;
@property (nonatomic, strong) CAEmitterCell *parentEmitterCell;
@end
  1. 初始化时绑定引用
    修改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];
}
  1. 触发时重置beginTime并设置birthRate
    修改StartFW方法,每次触发时将Parent单元格的beginTime重置为当前媒体时间,确保粒子从当前时间开始生成:
-(IBAction)StartFW {
    // 重置beginTime为当前时间,保证粒子生命周期从现在开始计算
    self.parentEmitterCell.beginTime = CACurrentMediaTime();
    // 直接设置birthRate,替代KVC方式更稳定
    self.parentEmitterCell.birthRate = 1;
}
  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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 21:07:28