1

ユーザーが正しく推測した後、Confetti エフェクトを作成したいと思います。Web を検索したところ、非常に良さそうなものが見つかりましたが、.m ファイルしかありません。ヘッダー ファイルをどうすればよいかわかりません。

これは紙吹雪効果リンクのあるページへのリンクです

これは .m ファイルそのものです。これらの行でエラーが発生します。

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

エラーが表示されるのはなぜですか?

//
// 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
4

1 に答える 1

1

これをリバースエンジニアリングするのはかなり簡単です。これは明らかにUIViewサブクラスなので、このようなもので十分です。最新の Objective-C では、実装ファイルでインスタンス変数を宣言する必要さえありません。

@interface SFSConfettiScreen : UIView

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

@end

これは、Xcode のバージョンが 4.4 以降の場合に機能するはずです。それ以外の場合は、実装をそのままにして宣言を削除し@property、空のインターフェイス宣言を残します。それもうまくいくはずです。私は、ivar よりもプロパティを好みます。

于 2012-12-01T21:23:50.217 に答える