9

我想创建一个仅在用户触摸屏幕时发射的粒子效果,但是一旦将 CAEmitterCellbirthRate 属性设置为非零值,我就无法更改它。

我有一个 UIView 的子类,它按照我想要的方式设置我的 CAEmitterLayer 和我的 CAEmitterCell。我在该类上定义了两个属性:

@property (strong, nonatomic) CAEmitterLayer *emitterLayer;
@property (strong, nonatomic) CAEmitterCell *emitterCell;

然后,在我的视图控制器中,我正在跟踪触摸,设置emitterLayer 的位置和emitterCell 出生率:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint tappedPt = [touch locationInView:touch.view];
    NSLog(@"began x:%f y:%f",tappedPt.x, tappedPt.y);
    emitterView.emitterCell.birthRate = 42;
    emitterView.emitterLayer.emitterPosition = tappedPt;
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint tappedPt = [touch locationInView:touch.view];
    NSLog(@"moved x:%f y:%f",tappedPt.x, tappedPt.y);
    emitterView.emitterLayer.emitterPosition = tappedPt;
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"ending %f", emitterView.emitterCell.birthRate);
    emitterView.emitterCell.birthRate = 0.00;
    NSLog(@"ended %f", emitterView.emitterCell.birthRate);
}

日志报告emitterView.emitterCell.birthRate 发生变化:

began x:402.000000 y:398.500000
ending 42.000000
ended 0.000000

当我触摸屏幕时,发射器按预期启动,层跟随触摸,但是当我结束触摸时,发射器单元愉快地发射初始设置的任何值(在 touchesBegan 中设置的值)。无论我做什么,一旦将出生率值设置为非零值,我似乎都无法更改。日志报告值设置正确,但发射器继续发射。

但是,如果我更改 touchesEnded 方法来更改图层的位置,在我在emitterCell 上设置birthRate 之后,一切都会按预期工作:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    CGPoint tappedPt = [touch locationInView:touch.view];
    NSLog(@"began x:%f y:%f",tappedPt.x, tappedPt.y);

    NSLog(@"ending %f", emitterView.emitterCell.birthRate);
    emitterView.emitterCell.birthRate = 0.0;
    NSLog(@"ended %f", emitterView.emitterCell.birthRate);
    emitterView.emitterLayer.emitterPosition = tappedPt;
}

有人可以解释为什么吗?

4

2 回答 2

7

要停止发射粒子,您必须将实例的birthRate属性设置CAEmitterLayer为 0,尽管它最初是在CAEmitterCell实例上设置的......不知道为什么,但它可以工作。

斯威夫特 3 示例:

func emitParticles() {
    let particlesEmitter = CAEmitterLayer()
    particlesEmitter.emitterPosition = center
    particlesEmitter.emitterShape = kCAEmitterLayerCircle
    particlesEmitter.emitterSize = CGSize(width: 50, height: 50)
    particlesEmitter.renderMode = kCAEmitterLayerAdditive

    let cell = CAEmitterCell()
    cell.birthRate = 15
    cell.lifetime = 1.0
    cell.color = bubble.color.cgColor
    cell.velocity = 150
    cell.velocityRange = 50
    cell.emissionRange = .pi
    cell.scale = 0.1
    cell.scaleSpeed = -0.1

    cell.contents = UIImage(named: "particle")?.cgImage
    particlesEmitter.emitterCells = [cell]

    layer.addSublayer(particlesEmitter)

    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
        particlesEmitter.birthRate = 0
    }
}
于 2017-05-14T20:33:19.690 回答
6

我不知道为什么它的行为有点奇怪,但我发现使用键值编码可以解决问题并且单元格停止发射:

假设您的 CAEmitterLayer 是“yourEmitterLayer”并且您有一个名为“yourEmitterCell”的 CAEmitterCell,如果放置在 touchesEnded 中,这将停止发射:

[yourEmitterLayer setValue:[NSNumber numberWithInt:0] forKeyPath:@"emitterCells.yourEmitterCell.birthRate"];
于 2013-05-27T20:28:01.223 回答