模仿qq背景点赞效果(干货)

我先上效果图

仿QQ照片墙点赞动画.gif

下面我把主要的代码展示上来


//
//  CxyThumbButton.m
//  空间点赞效果
//
//  Created by  on 2017/2/23.
//  Copyright © 2017年 崔心月. All rights reserved.
//

#import "CxyThumbButton.h"

#define RGB(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define RGBA(r, g, b ,a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:a]
#define randomCor RGB(arc4random_uniform(255), arc4random_uniform(255), arc4random_uniform(255))

@interface ZanImageView ()

@end

@implementation ZanImageView

-(instancetype)init{

    self = [super init];
    if (self) {
        
        self.image = [UIImage imageNamed:@"ZanFiger0"];
        UIImage *newImage = [self.image imageWithColor:randomCor];
        self.image = newImage;
    }
    return self;
}

@end


#define kZanWH 25.f
#define kXOffSet 30.f
#define kYOffSet 80.f
#define kButtonH 25.f
#define kThumbImgWH kButtonH/2
#define kNumLabelH kButtonH/2
#define kNumFont [UIFont systemFontOfSize:13.f]

@interface CxyThumbButton (){

    UIImage *_defImage; // 点赞前默认图片
    UIImage *_selImage; // 点赞后图片
    NSInteger _defCount; // 初始化时显示的点赞数
    NSInteger _count; // 已经点赞个数
    NSInteger _numLength; // 总点赞数长度

}


// 允许最大点赞数
@property(assign,nonatomic)NSInteger maxFingers;
// 点赞按钮左边手势
@property(nonatomic,strong)UIImageView *thumbImgView;
// 点赞按钮 赞数量
@property(nonatomic,strong)UILabel *numLabel;
// 动画显示那个点赞手势
@property(nonatomic,strong)ZanImageView *zanImgView;

@end

@implementation CxyThumbButton

-(instancetype)initWithOrigin:(CGPoint)origin defImage:(UIImage *)defImage selImage:(UIImage *)selImage defCount:(NSInteger)defCount maxFingers:(NSInteger)maxFingers{


    NSString *num = [NSString stringWithFormat:@"%ld",defCount];
    CGSize size = [num sizeWithFont:kNumFont maxSize:CGSizeMake(100.f, 20.f)];
    CGRect frame = CGRectMake(origin.x, origin.y, kThumbImgWH + size.width + 40.f, kButtonH);
    
    if (self = [super initWithFrame:frame]) {
        
        _count = 0;
        _defImage = defImage;
        _selImage = selImage;
        _defCount = defCount;
        _numLength = num.length;
        _maxFingers = maxFingers;
        [self setupSubViews];
    }

    return self;

}


-(UIImageView *)thumbImgView{

    if (!_thumbImgView) {
        
        _thumbImgView = [[UIImageView alloc]init];
        _thumbImgView.frame = CGRectMake(10.f+5.f, kButtonH / 4, kThumbImgWH, kThumbImgWH);
        _thumbImgView.image = _defImage;
        _thumbImgView.contentMode = UIViewContentModeCenter;
    }
    return _thumbImgView;
}


-(UILabel *)numLabel{

    if (!_numLabel) {
        _numLabel = [[UILabel alloc]init];
        _numLabel.font = kNumFont;
        NSString *num = [NSString stringWithFormat:@"%ld",_defCount];
        _numLabel.textColor = [UIColor whiteColor];
        _numLabel.text = num;
        CGSize size = [num sizeWithFont:kNumFont maxSize:CGSizeMake(100.f, 20.f)];
        _numLabel.frame = CGRectMake(10.f+kThumbImgWH+15.f, kButtonH / 4, size.width, kNumLabelH);
    }
    return _numLabel;
}


-(void)setupSubViews{

    [self addSubview:self.thumbImgView];
    [self addSubview:self.numLabel];
    
    self.layer.cornerRadius = 12.5f;
    self.layer.borderColor = [UIColor colorWithWhite:0.900 alpha:0.600].CGColor;
    self.layer.borderWidth = 0.5f;
    self.backgroundColor = [UIColor colorWithWhite:0.1 alpha:0.6];
    
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(thumbButtonClick)];
    
    [self addGestureRecognizer:tap];

}

-(void)thumbButtonClick{

    if (_count >= self.maxFingers && _maxFingers != 0) {
        
        // 点赞失败
        if (self.delegate && [self.delegate respondsToSelector:@selector(cxy_thumbFail)]) {
            [self.delegate cxy_thumbFail];
        }
        
        else if (self.cxy_thumbFailBlock){
        
            self.cxy_thumbFailBlock(YES);
        }else{
        
            NSLog(@"未设置代理或者回调,如果要获取点赞结果请设置");
        }
        return;
        
    }
    
    else{
    
        NSString *oriNum = self.numLabel.text;
        NSString *newNum = [NSString stringWithFormat:@"%d",[oriNum intValue]+1];
        self.numLabel.text = newNum;
        
        CGSize size = [newNum sizeWithFont:kNumFont maxSize:CGSizeMake(100.f, 20.f)];
        _numLabel.frame = CGRectMake(10.f+kThumbImgWH + 15.f, kButtonH / 4, size.width, kNumLabelH);
        
        if (newNum.length > _numLength) { // 如果点赞数长度发生变化,重新计算button的frame
            
            self.w = kThumbImgWH + 20.f + size.width + 10.f + 10.f;
            _numLength = newNum.length;
            [self setNeedsLayout];
        }
        
        self.thumbImgView.image = _selImage;
        
        NSInteger zans = [self.numLabel.text integerValue];
        
        if (self.delegate && [self.delegate respondsToSelector:@selector(cxy_thumbBtClick:)]) {
            
            [self.delegate cxy_thumbBtClick:zans];
        }else if (self.cxy_thumbClickBlock){
        
            self.cxy_thumbClickBlock(zans);
        }else{
        
            NSLog(@"未设置代理或者回调,如果要获取点赞结果请设置");
            
        }
        _count++;
        
    }
    
    
#pragma mark -- 动画
    CGPoint center = CGPointMake(self.w/2, self.h/2);
    UIImageView *zanImgView = [[ZanImageView alloc] init];
    zanImgView.center = center;
    zanImgView.alpha = 0.9f;
    zanImgView.bounds = CGRectMake(0.f, 0.f, 0.f, 0.f);
    
    // 向上移动
    NSInteger i = arc4random_uniform(2);
    NSInteger direction = 1 - (2*i);
    
    UIBezierPath *bezPath = [UIBezierPath bezierPath];
    [bezPath moveToPoint:center];
    CGPoint endPoint = CGPointMake(center.x, center.y-200.f);
    
    CGPoint cPoint1 = CGPointMake(center.x - kXOffSet*direction, -kYOffSet);
    CGPoint cPoint2 = CGPointMake(center.x + kXOffSet*direction, -kYOffSet);
    
    [bezPath addCurveToPoint:endPoint controlPoint1:cPoint1 controlPoint2:cPoint2];
    
    CAKeyframeAnimation *ani = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    ani.path = bezPath.CGPath;
    ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    ani.duration = 2.f;
    ani.removedOnCompletion = YES;
    [zanImgView.layer addAnimation:ani forKey:nil];
    
    // 先向上移动一小段距离
    [UIView animateWithDuration:0.1f animations:^{
        zanImgView.transform = CGAffineTransformMakeTranslation(0.f, -20.f);
    }];
    
    // 弹簧效果弹出
    [UIView animateWithDuration:0.2f delay:0.1f usingSpringWithDamping:0.5f initialSpringVelocity:50.f options:UIViewAnimationOptionCurveEaseOut animations:^{
        zanImgView.bounds = CGRectMake(0, 0, kZanWH, kZanWH);
    } completion:NULL];
    
    // 渐隐消失
    [UIView animateKeyframesWithDuration:2.f delay:0.f options:0.f animations:^{
        [self addSubview:zanImgView];
        [UIView addKeyframeWithRelativeStartTime:3/4.f relativeDuration:1/4.f animations:^{
            zanImgView.alpha = 0.f;
        }];
    } completion:^(BOOL finished) {
        [zanImgView removeFromSuperview];
    }];
}
@end

我将我的demo放到git上
传送门:https://github.com/JonesCxy/demo
欢迎star

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,907评论 25 707
  • 首先非常感谢tiger给我推荐了这本《黑天鹅》,更感谢他把这本书规定为一本不读不行的书,不然我也没有这么大...
    极端斯坦阅读 723评论 4 7
  • 风温柔地吹过脸脥/ 拂去了岁月多少繁华/ 我是/ 那只飞舞在草丛中的蝶/ 无论怎样/ 也找不到属于自己的花朵/ 任...
    草蝶阅读 304评论 0 1
  • 第三件开心事好报写作班 5月12日开始上课,我可不是一般高兴,是真的高兴,我又可以上学了。来的第一天接到一...
    爱花儿美阅读 158评论 1 4