类似QQ消息提醒数字的拖拉消除效果

使用注意:需要几张图片来演示最后的消除过程

声明:

1 // 自带酷炫效果的badgeBtn
2 #import <UIKit/UIKit.h>
3 
4 @interface YJBadgeBtn : UIButton
5 
6 @property (nonatomic, assign) int count;
7 @end

实现:

  1 #import "YJBadgeBtn.h"
  2 
  3 @interface YJBadgeBtn()
  4 
  5 @property (nonatomic, weak)  UIView *smallCircle;
  6 
  7 /** 形状图层 */
  8 @property (nonatomic, weak) CAShapeLayer *shapL;
  9 
 10 @end
 11 
 12 @implementation YJBadgeBtn
 13 
 14 -(CAShapeLayer *)shapL{
 15     
 16     if (_shapL == nil) {
 17         CAShapeLayer *shap = [CAShapeLayer layer];
 18         shap.fillColor = [UIColor redColor].CGColor;
 19         _shapL = shap;
 20         [self.superview.layer insertSublayer:shap atIndex:0];
 21     }
 22     return _shapL;
 23 }
 24 
 25 - (instancetype)initWithFrame:(CGRect)frame
 26 {
 27     self = [super initWithFrame:frame];
 28     if (self) {
 29         [self setTitle:@"..." forState:UIControlStateNormal];
 30         self.layer.cornerRadius = 10;
 31         self.backgroundColor = [UIColor redColor];
 32         self.titleLabel.font = [UIFont systemFontOfSize:12];
 33         [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
 34     }
 35     return self;
 36 }
 37 
 38 
 39 - (void)layoutSubviews
 40 {
 41     [super layoutSubviews];
 42     
 43     if (self.smallCircle) return;
 44     
 45     [self setUp];
 46 }
 47 - (void)setCount:(int)count
 48 {
 49     if (count > 99) {
 50         [self setTitle:@"99" forState:UIControlStateNormal];
 51     } else {
 52         [self setTitle:[NSString stringWithFormat:@"%d",count] forState:UIControlStateNormal];
 53     }
 54 }
 55 
 56 - (void)setUp
 57 {
 58     
 59     
 60     //添加手势
 61     UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
 62     [self addGestureRecognizer:pan];
 63     
 64     
 65     //添加小圆
 66     UIView *smallCircle = [[UIView alloc] init];
 67     smallCircle.backgroundColor = self.backgroundColor;
 68     smallCircle.layer.cornerRadius = self.layer.cornerRadius;
 69     smallCircle.frame = self.frame;
 70     self.smallCircle = smallCircle;
 71     
 72 //    [self.superview addSubview:smallCircle];
 73     [self.superview insertSubview:smallCircle belowSubview:self];
 74     
 75 }
 76 
 77 - (void)pan:(UIPanGestureRecognizer *)pan{
 78     
 79     //获取移动偏移量
 80     CGPoint transP =  [pan translationInView:self];
 81     //frame,center,transform.
 82     //transform它并不会去修改center.它修改的是frame.
 83     //self.transform = CGAffineTransformTranslate(self.transform, transP.x, transP.y);
 84     
 85     CGPoint center = self.center;
 86     center.x += transP.x;
 87     center.y += transP.y;
 88     self.center = center;
 89     
 90     //计算两个圆之间的距离
 91     CGFloat distance = [self distanceWithSmallCircle:self.smallCircle bigCirle:self];
 92     
 93     //获取小圆的半径
 94     CGFloat radius = self.bounds.size.width * 0.5;
 95     radius = radius - distance / 10.0;
 96     self.smallCircle.bounds = CGRectMake(0, 0, radius * 2, radius * 2);
 97     self.smallCircle.layer.cornerRadius = radius;
 98     
 99     
100     UIBezierPath *path = [self  pathWithSmallCircle:self.smallCircle bigCirle:self];
101     
102     //形状图层
103     if (self.smallCircle.hidden == NO) {
104         self.shapL.path = path.CGPath;
105     }
106     //判断 两个圆之间的距离
107     if(distance > 60){
108         self.smallCircle.hidden = YES;
109         //self.shapL.hidden = YES;
110         [self.shapL removeFromSuperlayer];
111     }
112     //判断手势的状态
113     if(pan.state == UIGestureRecognizerStateEnded){
114         
115         if (distance <= 60) {
116             self.center =  self.smallCircle.center;
117             self.smallCircle.hidden = NO;
118             [self.shapL removeFromSuperlayer];
119         }else{
120             //播放动画,消失
121             UIImageView *imageV = [[UIImageView alloc] initWithFrame:self.bounds];
122             
123             NSMutableArray *imageArray = [NSMutableArray array];
124             for (int i = 0;  i < 8; i++) {
125                 NSString *imageName = [NSString stringWithFormat:@"%d",i + 1];
126                 UIImage *image = [UIImage imageNamed:imageName];
127                 [imageArray addObject:image];
128             }
129             imageV.animationImages = imageArray;
130             [imageV setAnimationDuration:1];
131             [imageV startAnimating];
132             
133             //添加到按钮上
134             [self addSubview:imageV];
135             
136             dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
137                 [self removeFromSuperview];
138             });
139             
140             
141         }
142         
143     }
144     
145     //复位
146     [pan setTranslation:CGPointZero inView:self];
147     
148 }
149 
150 //计算两个圆之间的距离
151 - (CGFloat)distanceWithSmallCircle:(UIView *)smallCircle bigCirle:(UIView *)bigCircle{
152     
153     CGFloat offsetX = bigCircle.center.x - smallCircle.center.x;
154     CGFloat offsetY = bigCircle.center.y - smallCircle.center.y;
155     return  sqrt(offsetX * offsetX + offsetY * offsetY);
156 }
157 
158 //根据两个圆计算不规则的路径
159 - (UIBezierPath *)pathWithSmallCircle:(UIView *)smallCircle bigCirle:(UIView *)bigCircle {
160     
161     CGFloat x1 = smallCircle.center.x;
162     CGFloat y1 = smallCircle.center.y;
163     
164     CGFloat x2 = bigCircle.center.x;
165     CGFloat y2 = bigCircle.center.y;
166     
167     CGFloat d = [self distanceWithSmallCircle:smallCircle bigCirle:bigCircle];
168     
169     if (d <= 0) {
170         return nil;
171     }
172     
173     
174     CGFloat cosθ = (y2 - y1) / d;
175     CGFloat sinθ = (x2 - x1) / d;
176     
177     CGFloat r1 = smallCircle.bounds.size.width * 0.5;
178     CGFloat r2 = bigCircle.bounds.size.width * 0.5;
179     
180     //创建点
181     CGPoint pointA = CGPointMake(x1 - r1 * cosθ, y1 + r1 * sinθ);
182     CGPoint pointB = CGPointMake(x1 + r1 * cosθ, y1 - r1 * sinθ);
183     CGPoint pointC = CGPointMake(x2 + r2 * cosθ, y2 - r2 * sinθ);
184     CGPoint pointD = CGPointMake(x2 - r2 * cosθ, y2 + r2 * sinθ);
185     CGPoint pointO = CGPointMake(pointA.x + d * 0.5 * sinθ, pointA.y + d * 0.5 * cosθ);
186     CGPoint pointP = CGPointMake(pointB.x + d * 0.5 * sinθ, pointB.y + d * 0.5 * cosθ);
187     
188     
189     UIBezierPath *path = [UIBezierPath bezierPath];
190     //AB
191     [path moveToPoint:pointA];
192     [path addLineToPoint:pointB];
193     //BC(曲线)
194     [path addQuadCurveToPoint:pointC controlPoint:pointP];
195     //CD
196     [path addLineToPoint:pointD];
197     //DA(曲线)
198     [path addQuadCurveToPoint:pointA controlPoint:pointO];
199     
200     return path;
201 }
202 
203 //取消高亮状态
204 -(void)setHighlighted:(BOOL)highlighted{
205 }
206 
207 @end

 

转载于:https://www.cnblogs.com/llinsline/p/5369231.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值