CoreAnimation-仿抖音点赞动画

525 阅读1分钟

先上效果

菥菥菥-2021-10-10-16.03.gif

首先我们来分析下

点赞效果:分为两部分,一个是红色心进行了旋转,缩放和透明度的变化,一个是六个三角形首先进行了从0-1的缩放,接着三角形向底边进行收缩(这里我们可以通过修改path来实现)

取消点赞效果:红色心进行了旋转加缩放,然后设置隐藏

上代码

1.创建默认状态和选中状态的两张图片

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self) {

        //添加点赞图片及手势

        [self addSubview:self.likeBefore];

        [self addSubview:self.likeAfter];

    }
    return self;
}

- (UIImageView *)likeBefore
{

    if (!_likeBefore) {

        _likeBefore = [[UIImageView alloc] initWithFrame:self.bounds];

        _likeBefore.contentMode = UIViewContentModeCenter;

        _likeBefore.image = [UIImage imageNamed:@"icon_home_like_before"];

        _likeBefore.tag = ZanLikeViewBeforeTag;

        _likeBefore.userInteractionEnabled = YES;

        [_likeBefore addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action: @selector(handleGesture:)]];

    }
    return _likeBefore;
}


- (UIImageView *)likeAfter
{
    if (!_likeAfter) {

        _likeAfter = [[UIImageView alloc] initWithFrame:self.bounds];

        _likeAfter.contentMode = UIViewContentModeCenter;

        _likeAfter.image = [UIImage imageNamed:@"icon_home_like_after"];

        _likeAfter.tag = ZanLikeViewAfterTag;

        _likeAfter.userInteractionEnabled = YES;

        [_likeAfter addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action: @selector(handleGesture:)]];

        _likeAfter.hidden = YES;

    }
    return _likeAfter;
}

2.设置点赞效果

- (void)startLikeAnimate
{
    CGFloat length = 30;

    CGFloat duration = self.likeDuration > 0 ? self.likeDuration : 0.5f;

    //创建6个三角形

    for (int i = 0; i < 6; i++) {

        CAShapeLayer *layer = [CAShapeLayer layer];

        layer.position = _likeBefore.center;

        layer.fillColor = self.zanFillColor == nil ? [UIColor redColor].CGColor : self.zanFillColor.CGColor;

        
        UIBezierPath *startPath = [UIBezierPath bezierPath];

        [startPath moveToPoint:CGPointMake(-2, -length)];

        [startPath addLineToPoint:CGPointMake(2, -length)];

        [startPath addLineToPoint:CGPointMake(0, 0)];

        layer.path = startPath.CGPath;

        layer.transform = CATransform3DMakeRotation(M_PI / 3.0f * i, 0.0, 0.0, 1.0);

        [self.layer addSublayer:layer];


        //创建动画组

        CAAnimationGroup *group = [CAAnimationGroup animation];

        group.removedOnCompletion = NO;

        group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

        group.fillMode = kCAFillModeForwards;

        group.duration = duration;

        //先做一个放大的动画

        CABasicAnimation *scaleAnim = [CABasicAnimation animationWithKeyPath:@"transform.scale"];

        scaleAnim.fromValue = @0.0;

        scaleAnim.toValue = @1.0;

        scaleAnim.duration = duration * 0.2f;


        //再做一个路径的收缩动画

        UIBezierPath *endPath = [UIBezierPath bezierPath];

        [endPath moveToPoint:CGPointMake(-2, -length)];

        [endPath addLineToPoint:CGPointMake(2, -length)];

        [endPath addLineToPoint:CGPointMake(0, -length)];


        CABasicAnimation *pathAnim = [CABasicAnimation animationWithKeyPath:@"path"];

        pathAnim.fromValue = (__bridge id)layer.path;

        pathAnim.toValue = (__bridge id)endPath.CGPath;

        pathAnim.beginTime = duration * 0.2f;

        pathAnim.duration = duration * 0.8f;

        [group setAnimations:@[scaleAnim, pathAnim]];

        [layer addAnimation:group forKey:nil];

    }

    _likeAfter.hidden = NO;

    _likeAfter.alpha = 0.f;

    [UIView animateWithDuration:0.4f delay:0.2f usingSpringWithDamping:0.6f initialSpringVelocity:0.8f options:UIViewAnimationOptionCurveEaseIn animations:^{

        self.likeBefore.alpha = 0.f;

        self.likeAfter.alpha = 1.f;

        self.likeAfter.transform = CGAffineTransformScale(CGAffineTransformMakeRotation(0), 1.f, 1.f);

    } completion:^(BOOL finished) {

        self.likeBefore.alpha = 1.f;

        self.likeBefore.userInteractionEnabled = YES;

        self.likeAfter.userInteractionEnabled = YES;

    }];

}

3.设置取消点赞效果

- (void)stopLikeAnimate
{
    [UIView animateWithDuration:0.35f delay:0.f options:UIViewAnimationOptionCurveEaseIn animations:^{

        self.likeAfter.alpha = 1.f;

        self.likeAfter.transform = CGAffineTransformScale(CGAffineTransformMakeRotation(-M_PI_4), 0.1f, 0.1f);;

    } completion:^(BOOL finished) {

        [self.likeAfter setHidden:YES];

        self.likeBefore.userInteractionEnabled = YES;

        self.likeAfter.userInteractionEnabled = YES;

    }];
}