欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

iOS之仿QQ点赞按钮粒子效果的实现

程序员文章站 2022-05-28 14:34:04
...

效果展示

iOS之仿QQ点赞按钮粒子效果的实现

具体流程

一、封装YDWLikeButton
  • 新建一个YDWLikeButton继承于UIButton,然后声明一个属性:
@property (nonatomic, strong) CAEmitterLayer *explosionLayer;

- (void)awakeFromNib{
    [super awakeFromNib];
    // 设置粒子效果
    [self setupExplosion];
}

- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        [self setupExplosion];
    }
    return self;
}

  • 设置粒子
	// 粒子
    CAEmitterCell * explosionCell = [CAEmitterCell emitterCell];
    explosionCell.name = @"explosionCell";
    // 透明值变化速度
    explosionCell.alphaSpeed = -1.f;
    // alphaRange透明值范围
    explosionCell.alphaRange = 0.10;
    // 生命周期
    explosionCell.lifetime = 1;
    // 生命周期range
    explosionCell.lifetimeRange = 0.1;
    // 粒子速度
    explosionCell.velocity = 40.f;
    // 粒子速度范围
    explosionCell.velocityRange = 10.f;
    // 缩放比例
    explosionCell.scale = 0.08;
    // 缩放比例range
    explosionCell.scaleRange = 0.02;
    // 粒子图片
    explosionCell.contents = (id)[[UIImage imageNamed:@"spark_red"] CGImage];	
  • 设置发射源
	// 发射源
    CAEmitterLayer * explosionLayer = [CAEmitterLayer layer];
    [self.layer addSublayer:explosionLayer];
    self.explosionLayer = explosionLayer;
    // 发射源尺寸大小
    self.explosionLayer.emitterSize = CGSizeMake(self.bounds.size.width + 40, self.bounds.size.height + 40);
    // emitterShape表示粒子从什么形状发射出来,圆形形状
    explosionLayer.emitterShape = kCAEmitterLayerCircle;
    // emitterMode发射模型,轮廓模式,从形状的边界上发射粒子
    explosionLayer.emitterMode = kCAEmitterLayerOutline;
    // renderMode:渲染模式
    explosionLayer.renderMode = kCAEmitterLayerOldestFirst;
    // 粒子cell 数组
    explosionLayer.emitterCells = @[explosionCell];
  • 选中状态,实现缩放
 - (void)setSelected:(BOOL)selected{
    [super setSelected:selected];
    
    // 通过关键帧动画实现缩放
    CAKeyframeAnimation * animation = [CAKeyframeAnimation animation];
    // 设置动画路径
    animation.keyPath = @"transform.scale";
    
    if (selected) {
        // 从没有点击到点击状态 会有爆炸的动画效果
        animation.values = @[@1.5,@2.0, @0.8, @1.0];
        animation.duration = 0.5;
        // 计算关键帧方式
        animation.calculationMode = kCAAnimationCubic;
        // 为图层添加动画
        [self.layer addAnimation:animation forKey:nil];
        
        // 让放大动画先执行完毕 再执行爆炸动画
        [self performSelector:@selector(startAnimation) withObject:nil afterDelay:0.25];
    } else {
        // 从点击状态normal状态 无动画效果 如果点赞之后马上取消 那么也立马停止动画
        [self stopAnimation];
    }
}
  • 开始动画和结束动画
/**
 * 开始动画
 */
- (void)startAnimation{
    
    // 用KVC设置颗粒个数
    [self.explosionLayer setValue:@1000 forKeyPath:@"emitterCells.explosionCell.birthRate"];
    
    // 开始动画
    self.explosionLayer.beginTime = CACurrentMediaTime();
    
    // 延迟停止动画
    [self performSelector:@selector(stopAnimation) withObject:nil afterDelay:0.15];
}

/**
 * 动画结束
 */
- (void)stopAnimation{
    // 用KVC设置颗粒个数
    [self.explosionLayer setValue:@0 forKeyPath:@"emitterCells.explosionCell.birthRate"];
    // 移除动画
    [self.explosionLayer removeAllAnimations];
}

二、使用YDWLikeButton
	YDWLikeButton * btn = [YDWLikeButton buttonWithType:UIButtonTypeCustom];
    btn.frame = CGRectMake(200, 150, 30, 130);
    [self.view addSubview:btn];
    [btn setImage:[UIImage imageNamed:@"dislike"] forState:UIControlStateNormal];
    [btn setImage:[UIImage imageNamed:@"like_orange"] forState:UIControlStateSelected];
    [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];

- (void)btnClick:(UIButton *)button{
    // 点赞
    if (!button.selected) {
        button.selected = !button.selected;
        NSLog(@"点赞");
    } else { // 取消点赞
        button.selected = !button.selected;
        NSLog(@"取消赞");
    }
}

完整示例传送门

仿QQ点赞按钮的粒子效果