iOS 使用核心動畫加粒子發射器實現的點贊按鈕

myxuee 8年前發布 | 8K 次閱讀 iOS開發 移動開發

1.使用到的類

CAKeyframeAnimation       // 核心動畫-關鍵幀動畫
CAEmitterLayer            // 粒子發射器(其實就是一個Layer,其父類是CALayer)
CAEmitterCell             // 粒子
PS:核心動畫應該不用多說了;
CAEmitterLayer和CAEmitterCell,其實可以比喻成“炮”和“炮彈”,應該不難理解;

2.直接上部分關鍵代碼 代碼中會有詳細的注釋

2.1 .m中需要擁有的屬性

/** weak類型 粒子發射器 */
@property (nonatomic, weak)  CAEmitterLayer *emitterLayer;

2.2 initWithFrame: 方法中

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // 配置粒子發射器方法
        [self setupEmitter];
    }
    return self;
}

2.3 setSelected: 方法中

- (void)setSelected:(BOOL)selected {
    [super setSelected:selected];
    // 開始關鍵幀動畫
    [self keyframeAnimation];
}

2.4 layoutSubviews 方法中

- (void)layoutSubviews{
    [super layoutSubviews];
    /// 設置粒子發射器的錨點
    _emitterLayer.position = self.imageView.center;  
}

2.5 setupEmitter 方法中( 配置粒子發射器方法 )

- (void)setup {
    // 粒子使用CAEmitterCell初始化
    CAEmitterCell *emitterCell   = [CAEmitterCell emitterCell];
    // 粒子的名字,在設置噴射個數的時候會用到
    emitterCell.name             = @"emitterCell";
    // 粒子的生命周期和生命周期范圍
    emitterCell.lifetime         = 0.7;
    emitterCell.lifetimeRange    = 0.3;
    // 粒子的發射速度和速度的范圍
    emitterCell.velocity         = 30.00;
    emitterCell.velocityRange    = 4.00;
    // 粒子的縮放比例和縮放比例的范圍
    emitterCell.scale            = 0.1;
    emitterCell.scaleRange       = 0.02;

    // 粒子透明度改變范圍
    emitterCell.alphaRange       = 0.10;
    // 粒子透明度在生命周期中改變的速度
    emitterCell.alphaSpeed       = -1.0;
    // 設置粒子的圖片
    emitterCell.contents         = (id)[UIImage imageNamed:@"Sparkle3"].CGImage;

    /// 初始化粒子發射器
    CAEmitterLayer *layer        = [CAEmitterLayer layer];
    // 粒子發射器的 名稱
    layer.name                   = @"emitterLayer";
    // 粒子發射器的 形狀(可以想象成打仗時,你需要的使用的炮的形狀)
    layer.emitterShape           = kCAEmitterLayerCircle;
    // 粒子發射器 發射的模式
    layer.emitterMode            = kCAEmitterLayerOutline;
    // 粒子發射器 中的粒子 (炮要使用的炮彈)
    layer.emitterCells           = @[emitterCell];
    // 定義粒子細胞是如何被呈現到layer中的
    layer.renderMode             = kCAEmitterLayerOldestFirst;
    // 不要修剪layer的邊界
    layer.masksToBounds          = NO;
    // z 軸的相對坐標 設置為-1 可以讓粒子發射器layer在self.layer下面
    layer.zPosition              = -1;
    // 添加layer
    [self.layer addSublayer:layer];
    _emitterLayer = layer;
}

ps:這里有一點需要詳細解釋一下, CAEmitterCell 的屬性一般有兩個參數:一個平均值和一個“Range”,比如:

// 粒子的生命周期和生命周期范圍
  emitterCell.lifetime         = 0.7;
  emitterCell.lifetimeRange    = 0.3;

這里蘋果的官方文檔是這樣解釋的:

每一個Layer都有它自己的隨機數發生器,粒子的屬性大部分都被定義為一個平均值和一個范圍值,
如粒子的速度,這個屬性的值分布的區間為:[ M - R / 2,M + R / 2 ]。

然后 這個公式里面
M:均值(拿上面代碼說就是 emitterCell.lifetime)
R:范圍值(mitterCell.lifetimeRange)

然后我們就可根據公式算出上面我設置的粒子的生命周期的范圍是[0.7-0.3/2 , 0.7+0.3/2]

2.6 keyframeAnimation 方法中 (開始關鍵幀動畫)

- (void)animation {
     // 創建關鍵幀動畫 
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
    if (self.selected) {
        animation.values = @[@1.5 ,@0.8, @1.0,@1.2,@1.0];
        animation.duration = 0.5;
        // 粒子發射器 發射
        [self startFire];
    }else
    {
        animation.values = @[@0.8, @1.0];
        animation.duration = 0.4;
    }
    // 動畫模式
    animation.calculationMode = kCAAnimationCubic;
    [self.imageView.layer addAnimation:animation forKey:@"transform.scale"];
}

這段代碼沒什么說的,應該很容易理解。

2.7 startFire 方法中 (開炮)

- (void)startFire{
    // 每秒噴射的80個
    [self.emitterLayer setValue:@1000 forKeyPath:@"emitterCells.emitterCell.birthRate"];
    // 開始
    self.emitterLayer.beginTime = CACurrentMediaTime();
    // 執行停止
    [self performSelector:@selector(stopFire) withObject:nil afterDelay:0.1];

}

2.8 stopFire 方法中 (停火)

- (void)stopFire {
    //每秒噴射的個數0個 就意味著關閉了
    [self.emitterLayer setValue:@0 forKeyPath:@"emitterCells.emitterCell.birthRate"];  
}

最后放兩張效果圖

 

來自:http://www.cocoachina.com/ios/20161202/18267.html

 

 本文由用戶 myxuee 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!