So I have developed an app using CAEmitterLayer. Initially I made it to emit automatically (when the app loads, it will start emitting the sparkles), it worked fine both in simulator and device.
Now, I changed it to emit when user taps on the screen. It works fine in simulator. On device, its not reacting. Please assist me in the right direction.
Initialized tap in -viewDidLoad
tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
Assigned in -viewWillAppear
tap setNumberOfTapsRequired:1];
[self.view addGestureRecognizer:tap];
- (void) particles {
if (!sparkling) {
rootLayer = [CALayer layer];
rootLayer.bounds = CGRectMake(0, 0, 320, 480);
CGColorRef color = [[UIColor clearColor] CGColor];
rootLayer.backgroundColor = color;
CGColorRelease(color);
const char* fileName = [[[NSBundle mainBundle] pathForResource:@"DazStarOutline" ofType:@"png"] UTF8String];
CGDataProviderRef dataProvider = CGDataProviderCreateWithFilename(fileName);
id img = (__bridge id)CGImageCreateWithPNGDataProvider(dataProvider, NULL, NO, kCGRenderingIntentDefault);
const char* fileNameR = [[[NSBundle mainBundle] pathForResource:@"DazRing" ofType:@"png"] UTF8String];
CGDataProviderRef dataProviderR = CGDataProviderCreateWithFilename(fileNameR);
id imgR = (__bridge id)CGImageCreateWithPNGDataProvider(dataProviderR, NULL, NO, kCGRenderingIntentDefault);
mortor = [CAEmitterLayer layer];
mortor.emitterPosition = CGPointMake(320, 0);
mortor.renderMode = kCAEmitterLayerAdditive;
CAEmitterCell *rocket = [CAEmitterCell emitterCell];
rocket.emissionLongitude = M_PI / 2;
rocket.emissionLatitude = 0;
rocket.lifetime = 2.0;
rocket.birthRate = 1;
rocket.velocity = 400;
rocket.velocityRange = 100;
rocket.yAcceleration = -250;
rocket.emissionRange = M_PI / 4;
color = [[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:0.5] CGColor];
rocket.color = color;
CGColorRelease(color);
rocket.redRange = 0.5;
rocket.greenRange = 0.5;
rocket.blueRange = 0.5;
CAEmitterCell *spark = [CAEmitterCell emitterCell];
spark.contents = img;
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, nil];
mortor.emitterCells = [NSArray arrayWithObjects:rocket, nil];
[rootLayer addSublayer:mortor];
[self.view.layer addSublayer:rootLayer];
sparkling = TRUE;
}
}
Tap Gesture Method
- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer {
[self particles];
}
So I downloaded your project. Two issues – one is that the CFRelease is not proper – you don’t own that color. But more important, if you take a color from a UIColor CGColor, you should really use the CG method to copy the color, then manage that resource. I know this gets complex, but when you mix CG and UI you will get complexity – you cannot avoid it.
I took your project, converted to ARC, then also created strong ivars that hold the UIColors that you want to use (as CGColorRefs). You cannot create a tempt UIColor, ask it for its CGColorRef, then expect that color to be around when the UIColor goes away.
The slightly modified project, it works great on the simulator and device (iPhone 4).
[Note – really nice use of CAEmitter – pretty!!!]