Cowboy Tech

使用带粒子效果的CAEmitterLayer

用CAEmitterLayer产生粒子效果

  1. CAEmitterLayer的用途
  2. CAEmitterLayer的一些重要参数
  3. 为什么要使用CAEmitterLayer

代码

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 创建出Layer
CAEmitterLayer *emitterLayer = [CAEmitterLayer layer];
// 显示边框
emitterLayer.borderWidth = 1.f;

// 给定尺寸
emitterLayer.frame = CGRectMake(100, 100, 100, 100);

// 发射点
emitterLayer.emitterPosition = CGPointMake(0, 0);

// 发射模式
emitterLayer.emitterMode = kCAEmitterLayerSurface;

// 发射形状
emitterLayer.emitterShape = kCAEmitterLayerLine;

// 添加layer
[self.view.layer addSublayer:emitterLayer];

// 创建粒子
CAEmitterCell *cell = [CAEmitterCell emitterCell];

// 粒子产生率
cell.birthRate = 10.f;

// 粒子生命周期
cell.lifetime = 10.f;

// 速度值
cell.velocity = 10;

// 速度值的微调值
cell.velocityRange = 3.f;

// y轴加速度
cell.yAcceleration = 2.f;

// 发射角度
cell.emissionRange = 4.f * M_1_PI;

// 设置粒子颜色
cell.color = [UIColor blackColor].CGColor;

// 设置图片
cell.contents = (__bridge id)([UIImage imageNamed:@"snow"].CGImage);

// 让CAEmitterCell与CAEmitterLayer产生关联
emitterLayer.emitterCells = @[cell];
}

封装CAEmitterLayer

  1. 替换CAEmitterLayer成UIView子类的backedLayer
  2. 将CAEmitterLayer封装的类作为“抽象”父类

代码

viewController.m

#import "ViewController.h"
#import "CAEmitterLayerView.h"
@interface ViewController ()
@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];
CAEmitterLayerView *layerView = [[CAEmitterLayerView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
NSLog(@"%@", layerView.layer);
}

@end

CAEmitterLayerView.m

#import "CAEmitterLayerView.h"

@interface CAEmitterLayerView () {
CAEmitterLayer  *_emitterLayer;
}
@end

@implementation CAEmitterLayerView

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

- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {    
    _emitterLayer = (CAEmitterLayer *)self.layer;
}
return self;
}

- (void)show {
}

- (void)hide {
}

- (void)setEmitterLayer:(CAEmitterLayer *)layer {
_emitterLayer = layer;
}

- (CAEmitterLayer *)emitterLayer {
return _emitterLayer;
}
@end

封装下雪下雨的粒子效果控件

  1. 从封装CAEmitterLayer的“抽象”父类继承的原因
  2. 下雪、下雨效果参数的设置

代码

viewController.m

- (void)viewDidLoad {
[super viewDidLoad];

UIImageView *alphaView1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
alphaView1.image        = [UIImage imageNamed:@"alpha"];

// 添加下雪效果
CAEmitterLayerView *snowView = [[SnowView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
snowView.maskView            = alphaView1;
[self.view addSubview:snowView];
[snowView show];

}

SnowView.m (继承CAEmitterLayerView,见上)

#import "SnowView.h"

@implementation SnowView

- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
    // 初始化设置
    [self setup];
}
return self;
}

- (void)setup {
self.emitterLayer.masksToBounds   = YES;
self.emitterLayer.emitterShape    = kCAEmitterLayerLine;
self.emitterLayer.emitterMode     = kCAEmitterLayerSurface;
self.emitterLayer.emitterSize     = self.frame.size;
self.emitterLayer.emitterPosition = CGPointMake(self.bounds.size.width / 2.f, - 20);
}

- (void)show {
// 配置
CAEmitterCell *snowflake  = [CAEmitterCell emitterCell];
snowflake.birthRate       = 1.f;
snowflake.speed           = 10.f;
snowflake.velocity        = 2.f;
snowflake.velocityRange   = 10.f;
snowflake.yAcceleration   = 10.f;
snowflake.emissionRange   = 0.5 * M_PI;
snowflake.spinRange       = 0.25 * M_PI;
snowflake.contents        = (__bridge id)([UIImage imageNamed:@"snow"].CGImage);
snowflake.color           = [UIColor redColor].CGColor;
snowflake.lifetime        = 60.f;
snowflake.scale           = 0.5;
snowflake.scaleRange      = 0.3;

// 添加动画
self.emitterLayer.emitterCells = @[snowflake];
}

@end

指定UIView的layer class

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