仿qq黏性demo
来源:互联网 发布:js中offsettop 编辑:程序博客网 时间:2024/05/29 11:51
//// AceCuteView.m// LayerDemo1//// Created by jackren on 16/3/9.// Copyright © 2016年 jackren. All rights reserved.//#import "AceCuteView.h"@interface AceCuteView (){ CGFloat r1; // backView CGFloat r2; // frontView CGFloat x1; CGFloat y1; CGFloat x2; CGFloat y2; CGFloat centerDistance; CGFloat cosDigree; CGFloat sinDigree; CGPoint pointA; //A CGPoint pointB; //B CGPoint pointD; //D CGPoint pointC; //C CGPoint pointO; //O CGPoint pointP; //P}@property UIView *backView;@property UIView *frontView;@property UILabel *label;@property CAShapeLayer *BezierLayer;@end@implementation AceCuteView-(instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { [self setUp]; [self addGesture]; _BezierLayer = [CAShapeLayer layer]; _BezierLayer.lineWidth = 1; _BezierLayer.fillColor = _bgColor.CGColor; [self.layer insertSublayer:_BezierLayer atIndex:0]; } return self;}-(void)setUp{ _bgColor = [UIColor redColor]; CGFloat DefaultSize = CGRectGetHeight(self.frame); _backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, DefaultSize, DefaultSize)]; _backView.backgroundColor = self.bgColor; _backView.layer.cornerRadius = CGRectGetHeight(_backView.frame)/2; _backView.center = CGPointMake(self.frame.size.width/2, self.frame.size.height/2); [self addSubview:_backView]; _frontView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.frame), DefaultSize)]; _frontView.backgroundColor = self.bgColor; _frontView.layer.cornerRadius = DefaultSize/2; [self addSubview:_frontView]; _label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.frame), DefaultSize)]; _label.backgroundColor = [UIColor clearColor]; _label.textColor = [UIColor whiteColor]; _label.textAlignment = NSTextAlignmentCenter; _label.layer.cornerRadius = DefaultSize/2; _label.text = @"13"; if (_bubbleText.length>0) { _label.text = _bubbleText; } [self.frontView addSubview:_label];}-(void)addGesture{ UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(doHandlePanAction:)]; [_frontView addGestureRecognizer:pan];}- (void)doHandlePanAction:(UIPanGestureRecognizer *)paramSender{ CGPoint point = [paramSender translationInView:self]; paramSender.view.center = CGPointMake(paramSender.view.center.x + point.x, paramSender.view.center.y + point.y); [paramSender setTranslation:CGPointMake(0, 0) inView:self]; //粘度设置 if (_viscosity == 0) { _viscosity = 50; } if (_viscosity < 30) { _viscosity = 30; } if (_viscosity > 90) { _viscosity = 90; } [self addBezierPathLayer:_BezierLayer]; if (paramSender.state == UIGestureRecognizerStateBegan) { _backView.hidden = NO; } if (paramSender.state == UIGestureRecognizerStateChanged) { if (centerDistance>_viscosity) { _BezierLayer.path = nil; _backView.hidden = YES; } else { _backView.hidden = NO; } } if (paramSender.state == UIGestureRecognizerStateEnded || paramSender.state ==UIGestureRecognizerStateCancelled || paramSender.state == UIGestureRecognizerStateFailed) { //距离50以内没问题 if (centerDistance < _viscosity) { _BezierLayer.path = nil; _backView.hidden = YES; [UIView animateWithDuration:0.3 delay:0.0f usingSpringWithDamping:0.2f initialSpringVelocity:0.6f options:UIViewAnimationOptionCurveEaseInOut animations:^{ paramSender.view.center = _backView.center; } completion:nil]; } else { //距离50外 [self removeFromSuperview]; } } }-(void)addBezierPathLayer:(CAShapeLayer *)layer{ x1 = _backView.center.x; y1 = _backView.center.y; x2 = _frontView.center.x; y2 = _frontView.center.y; centerDistance = sqrtf((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); CGFloat size = self.frame.size.height-centerDistance*0.2; _backView.frame = CGRectMake(0, 0, size, size); _backView.center = CGPointMake(x1, y1); _backView.layer.cornerRadius = CGRectGetWidth(_backView.frame)/2; #if 1 r1 = _backView.frame.size.height/2; r2 = _frontView.frame.size.height/2; if (centerDistance == 0) { cosDigree = 1; sinDigree = 0; }else{ cosDigree = (y2-y1)/centerDistance; sinDigree = (x2-x1)/centerDistance; } float m = 2; pointA = CGPointMake(x1-r1*cosDigree, y1+r1*sinDigree); // A pointB = CGPointMake(x1+r1*cosDigree, y1-r1*sinDigree); // B pointD = CGPointMake(x2-r2*cosDigree, y2+r2*sinDigree); // D pointC = CGPointMake(x2+r2*cosDigree, y2-r2*sinDigree);// C pointO = CGPointMake(pointA.x + (centerDistance / m)*sinDigree, pointA.y + (centerDistance / m)*cosDigree); pointP = CGPointMake(pointB.x + (centerDistance / m)*sinDigree, pointB.y + (centerDistance / m)*cosDigree); UIBezierPath *path = [UIBezierPath bezierPath]; //B→C D→A 需要贝赛尔曲线 [path moveToPoint:pointA]; [path addQuadCurveToPoint:pointD controlPoint:pointO]; [path addLineToPoint:pointC]; [path addQuadCurveToPoint:pointB controlPoint:pointP]; [path moveToPoint:pointA]; layer.path = path.CGPath; #endif}@end下载地址:Demo
1 0
- 仿qq黏性demo
- 仿QQ聊天列表界面demo
- vue-仿手机qq的demo
- 仿QQ空间滚动ActionBar透明度变化Demo
- android 仿QQ列表可折叠+自定义Dialog结合的DEMO
- 仿QQ消息提示小圆点---启发demo
- 仿QQ侧滑删除Item效果Demo
- 仿QQ空间滚动ActionBar透明度变化Demo
- iOS版QQ的黏性下拉刷新效果简易实现
- 仿QQ使用JAVA、C#、JS基于TCP交互的Demo
- 仿qq联系人分层list&&分组悬浮向上滚动效果 最简化demo
- Android学习小Demo(18)Todo List 仿QQ删除任务
- Android UI设计: 仿QQ好友列表分组悬停,自定义Header,下拉刷新结合Demo
- 0831Android基础自定义Notification+仿QQ聊天界面的小Demo(上)
- html5 websocket java 联合开发---仿qq多人在线聊天demo
- android仿QQ空间滚动ActionBar透明度变化Demo(带源码)
- 仿淘点点 demo
- 仿QQ导航菜单
- C#使用 MonoGame* 开发游戏
- bootstrap 的格栅
- 4、快速排序法QuickSort()+Partition()
- C语言实现的压力测试代码
- [LeetCode]150. Evaluate Reverse Polish Notation
- 仿qq黏性demo
- Free 命令
- Service之AIDL
- JS 利用 for in 循环获取 一个对象的所有属性以及值
- android封装get请求
- 从1到n整数中1出现的次数(比如121这一个整数里就含有两个1)
- React学习之进阶上下文(十九)
- 风险度量
- Vue.js音乐