iOS QQ粘性布局
来源:互联网 发布:瘦身 知乎 编辑:程序博客网 时间:2024/04/28 03:57
Demo下载地址:http://download.csdn.net/download/u010981736/9964836
iOS 仿照QQ未读消息提醒数字的粘性布局,实现了和QQ未读消息一样的功能,拖拽的时候会有粘性效果,在一定范围内拖拽松手还会回到原来的位置,超过一定距离之后就会播放一个动画。
效果图:
核心代码:
//// BageValueBtn.m// QQ粘性布局//// Created by llkj on 2017/9/5.// Copyright © 2017年 LayneCheung. All rights reserved.//#import "BageValueBtn.h"@interface BageValueBtn()@property (nonatomic, weak) UIView *smallCircle;@property (nonatomic, weak) CAShapeLayer *shap;@end@implementation BageValueBtn-(void)awakeFromNib{ [super awakeFromNib]; [self setUP];}-(instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { [self setUP]; } return self;}-(CAShapeLayer *)shap{ if (_shap == nil) { //形状图层 //它可以根据一个路径生成一个形状. CAShapeLayer *shap = [CAShapeLayer layer]; //设置形状的填充颜色 shap.fillColor = [UIColor redColor].CGColor; _shap = shap; [self.superview.layer insertSublayer:shap atIndex:0]; } return _shap;}//初始化- (void)setUP{ //设置圆角 self.layer.cornerRadius = self.bounds.size.width * 0.5; //设置背景颜色 [self setBackgroundColor:[UIColor redColor]]; [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; self.titleLabel.font = [UIFont systemFontOfSize:12]; //添加手势 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; [self addGestureRecognizer:pan]; //添加小圆 UIView *smallCircle = [[UIView alloc] init]; smallCircle.frame = self.frame; smallCircle.backgroundColor = self.backgroundColor; smallCircle.layer.cornerRadius = self.layer.cornerRadius; self.smallCircle = smallCircle; [self.superview insertSubview:smallCircle belowSubview:self];}//计算两个圆之间的距离- (CGFloat)distanceWithSmallCircle:(UIView *)smallCircle bigCircle:(UIView *)bigCircle{ //X轴偏移量 CGFloat offsetX = bigCircle.center.x - smallCircle.center.x; //Y轴偏移量 CGFloat offsetY = bigCircle.center.y - smallCircle.center.y; return sqrtf(offsetX * offsetX + offsetY * offsetY);}//根据两个圆设置一个不规则的路径- (UIBezierPath *)pathWithSmallCircle:(UIView *)smallCircle bigCircle:(UIView *)bigCircle{ CGFloat x1 = smallCircle.center.x; CGFloat y1 = smallCircle.center.y; CGFloat x2 = bigCircle.center.x; CGFloat y2 = bigCircle.center.y; CGFloat d = [self distanceWithSmallCircle:smallCircle bigCircle:self]; if (d <= 0) { return nil; } CGFloat cosθ = (y2 - y1) / d; CGFloat sinθ = (x2 - x1) / d; CGFloat r1 = smallCircle.bounds.size.width * 0.5; CGFloat r2 = bigCircle.bounds.size.width * 0.5; CGPoint pointA = CGPointMake(x1 - r1 * cosθ, y1 + r1 * sinθ); CGPoint pointB = CGPointMake(x1 + r1 * cosθ, y1 - r1 * sinθ); CGPoint pointC = CGPointMake(x2 + r2 * cosθ, y2 - r2 * sinθ); CGPoint pointD = CGPointMake(x2 - r2 * cosθ, y2 + r2 * sinθ); CGPoint pointO = CGPointMake(pointA.x + d * 0.5 * sinθ, pointA.y + d * 0.5 * cosθ); CGPoint pointP = CGPointMake(pointB.x + d * 0.5 * sinθ, pointB.y + d * 0.5 * cosθ); UIBezierPath *path = [UIBezierPath bezierPath]; //AB [path moveToPoint:pointA]; [path addLineToPoint:pointB]; //BC(曲线) [path addQuadCurveToPoint:pointC controlPoint:pointP]; //CD [path addLineToPoint:pointD]; //DA(曲线) [path addQuadCurveToPoint:pointA controlPoint:pointO]; return path;}- (void)pan:(UIPanGestureRecognizer *)pan{ //frame,center,transform. //移动. CGPoint transP = [pan translationInView:self]; //修改transform值,并没有去修改center,它修改的frame // self.transform = CGAffineTransformTranslate(self.transform, transP.x, transP.y); CGPoint center = self.center; center.x += transP.x; center.y += transP.y; self.center = center; //复位 [pan setTranslation:CGPointZero inView:self]; //两个圆之间的距离 CGFloat distance = [self distanceWithSmallCircle:self.smallCircle bigCircle:self]; //让小圆的半径减去距离的比例 //获取小圆的半径 CGFloat smallR = self.bounds.size.width * 0.5; smallR = smallR - distance / 10.0; //要重设置小圆的尺寸 self.smallCircle.bounds = CGRectMake(0, 0, smallR * 2, smallR * 2); //重新设置小圆的圆角 self.smallCircle.layer.cornerRadius = smallR; //不规则的路径. //如果小圆显示的时候再创建 if(self.smallCircle.hidden == NO){ UIBezierPath *path = [self pathWithSmallCircle:self.smallCircle bigCircle:self]; self.shap.path = path.CGPath; } //如果两个圆之间的距离超过某个范围.让小圆隐藏,shap移除 if(distance > 60){ self.smallCircle.hidden = YES; [self.shap removeFromSuperlayer]; } //当手指松开时,如果发现两个圆之间距离小于某个值时,大圆复位. if(pan.state == UIGestureRecognizerStateEnded){ //如果发现两个圆之间距离小于某个值时,大圆复位. if (distance < 60) { //移除形状 [self.shap removeFromSuperlayer]; //添加一个弹性动画 [UIView animateWithDuration:0.25 delay:0 usingSpringWithDamping:0.2 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{ //大圆复位. self.center = self.smallCircle.center; } completion:^(BOOL finished) { //让小圆显示 self.smallCircle.hidden = NO; }]; }else{ //如果发现两个圆之间距离大于某个值时,播放动画,按钮从父控件当中移. //添加一个UIImageView UIImageView *imageV = [[UIImageView alloc] initWithFrame:self.bounds]; NSMutableArray *imageArray = [NSMutableArray array]; for (int i = 0; i < 8; ++i) { NSString *imageName = [NSString stringWithFormat:@"%d",i + 1]; UIImage *image = [UIImage imageNamed:imageName]; [imageArray addObject:image]; } imageV.animationImages = imageArray; //设置动画的执行时长 [imageV setAnimationDuration:1]; //开始动画 [imageV startAnimating]; [self addSubview:imageV]; //一秒钟后.把当前的按钮从父控件当中移. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ //把当前的按钮从父控件当中移. [self removeFromSuperview]; }); } }}//取消高亮状态-(void)setHighlighted:(BOOL)highlighted{}/* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */@end
阅读全文
0 0
- iOS QQ粘性布局
- IOS开发UI基础:QQ粘性效果
- iOS核心动画 一一 QQ粘性效果
- IOS-QQ粘性效果(QQ消息提示红点)
- iOS几个效果动画-------------------(实例详讲)qq粘性效果
- 十七 iOS之 QQ提示标粘性效果
- Android 粘性布局CoordinatorLayout
- QQ粘性效果计算原理
- QQ聊天列表粘性控件
- 5.模仿QQ粘性控件
- 《仿QQ未读消息粘性按钮》
- QQ的粘性控件的实现原理
- 仿QQ消息红点粘性效果
- iOS粘性拖拽红点动画研究
- 使用 position-sticky 实现粘性布局
- 使用 position-sticky 实现粘性布局
- 使用 position-sticky 实现粘性布局
- 使用 position-sticky 实现粘性布局
- Spring框架(3.0)下的定时任务
- 在HLS的IP核中声明默认逻辑引脚
- weblogic 12 开启debug端口配置
- spark+mongodb大数据框架搭建
- 云主机-生产环境下离线安装Docker部署应用
- iOS QQ粘性布局
- Java基础学习总结(114)——System之系统变量和环境变量
- Android 判断程序在前台还是后台
- 标准IO与文件IO 的区别
- sql 优化
- 搭建一个完整平台
- Yii常用网站
- 自然连接
- js前端页面,对string字符串的处理函数和方法