I would like to create a particle effect that only emits while the user touches the screen, but I cannot change the CAEmitterCell birthRate property when set to a non-zero value.
I have a subclass of UIView that sets my CAEmitterLayer and my CAEmitterCell exactly the way I want them. I define two properties of this class:
@property (strong, nonatomic) CAEmitterLayer *emitterLayer; @property (strong, nonatomic) CAEmitterCell *emitterCell;
Then, in my opinion, the controller, I track the touches by setting the position of the emitterLayer and the birth rate of the emitterCell:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint tappedPt = [touch locationInView:touch.view]; NSLog(@"began x:%fy:%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:%fy:%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); }
The log says that emitterView.emitterCell.birthRate is changing:
began x:402.000000 y:398.500000 ending 42.000000 ended 0.000000
When I touch the screen, the emitter starts as expected, the layer follows the touch, but when I finish the touch, the emitter cell gladly emits any value that was originally set (the value is set in touchhesBegan). No matter what I do, I seem to be unable to change the birth rate after a non-zero value is set. The log reports that the values ββare set correctly, but the emitter continues to emit.
However, if I changed the touchesEnded method to change the position of the layer, after I set the birthRate value to emitterCell, everything will work as expected:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ UITouch *touch = [touches anyObject]; CGPoint tappedPt = [touch locationInView:touch.view]; NSLog(@"began x:%fy:%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; }
Can someone explain why?