Pregunta

I want to make Confetti effect after user guess correctly, I searched the web and found something that looks really good, but it only have the .m file, I don't have any idea what to do with the header file.

This is the link to the page with the Confetti effect link

This is the .m file itself, I get an error on those lines:

if ((self = [super initWithFrame:frame])) {
    self.userInteractionEnabled = NO;
    self.backgroundColor = [UIColor clearColor];
    _confettiEmitter = (CAEmitterLayer*)self.layer;

Why is the errors appears?

//
// Created by tdimson on 8/15/12.

#import <QuartzCore/QuartzCore.h>
#import "SFSConfettiScreen.h"


@implementation SFSConfettiScreen {
    __weak CAEmitterLayer *_confettiEmitter;
    CGFloat _decayAmount;
}

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        self.userInteractionEnabled = NO;
        self.backgroundColor = [UIColor clearColor];
        _confettiEmitter = (CAEmitterLayer*)self.layer;
        _confettiEmitter.emitterPosition = CGPointMake(self.bounds.size.width /2, 0);
        _confettiEmitter.emitterSize = self.bounds.size;
        _confettiEmitter.emitterShape = kCAEmitterLayerLine;

        CAEmitterCell *confetti = [CAEmitterCell emitterCell];
        confetti.contents = (__bridge id)[[UIImage imageNamed:@"Confetti.png"] CGImage];
        confetti.name = @"confetti";
        confetti.birthRate = 150;
        confetti.lifetime = 5.0;
        confetti.color = [[UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:1.0] CGColor];
        confetti.redRange = 0.8;
        confetti.blueRange = 0.8;
        confetti.greenRange = 0.8;

        confetti.velocity = 250;
        confetti.velocityRange = 50;
        confetti.emissionRange = (CGFloat) M_PI_2;
        confetti.emissionLongitude = (CGFloat) M_PI;
        confetti.yAcceleration = 150;
        confetti.scale = 1.0;
        confetti.scaleRange = 0.2;
        confetti.spinRange = 10.0;
        _confettiEmitter.emitterCells = [NSArray arrayWithObject:confetti];
    }

    return self;
}

+ (Class) layerClass {
    return [CAEmitterLayer class];
}

static NSTimeInterval const kDecayStepInterval = 0.1;
- (void) decayStep {
    _confettiEmitter.birthRate -=_decayAmount;
    if (_confettiEmitter.birthRate < 0) {
        _confettiEmitter.birthRate = 0;
    } else {
        [self performSelector:@selector(decayStep) withObject:nil afterDelay:kDecayStepInterval];
    }
}

- (void) decayOverTime:(NSTimeInterval)interval {
    _decayAmount = (CGFloat) (_confettiEmitter.birthRate /  (interval / kDecayStepInterval));
    [self decayStep];
}

- (void) stopEmitting {
    _confettiEmitter.birthRate = 0.0;
}

@end
¿Fue útil?

Solución

Should be pretty straightforward to reverse-engineer this. It's obviously a UIView subclass, so something like this should suffice, and in modern Objective-C, you don't even need to declare the instance variables in the implementation file.

@interface SFSConfettiScreen : UIView

@property(nonatomic, weak) CAEmitterLayer *confettiEmitter;
@property(nonatomic, assign) CGFloat decayAmount;

@end

This should work if your version of Xcode is 4.4 or newer, as it should be. Otherwise, leave the implementation as-is and remove the @property declarations, leaving an empty interface declaration. That should also work; I just prefer properties to ivars.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top