iOS悬浮窗口(无论界面跳转、View始终在视图上显示,可移动)

2016.09.24 23:52* 字数 71 阅读 5925评论 9

让所有界面都显示,最好还是封装一个继承Window的类:JYCWindow。

先看看效果:

 
mygif.gif

关键代码如下:

- (instancetype)initWithFrame:(CGRect)frame mainImageName:(NSString*)name bgcolor:(UIColor *)bgcolor animationColor:animationColor

{
    if(self = [super initWithFrame:frame]) { NSAssert(name != nil, @"mainImageName can't be nil !"); self.backgroundColor = [UIColor clearColor]; self.windowLevel = UIWindowLevelAlert + 1; //如果想在 alert 之上,则改成 + 2 self.rootViewController = [UIViewController new]; [self makeKeyAndVisible]; _bgcolor = bgcolor; _frameWidth = frame.size.width; _animationColor = animationColor; _mainImageButton = [UIButton buttonWithType:UIButtonTypeCustom]; [_mainImageButton setFrame:(CGRect){0, 0,frame.size.width, frame.size.height}]; [_mainImageButton setImage:[UIImage imageNamed:name] forState:UIControlStateNormal]; // _mainImageButton.layer.cornerRadius = frame.size.width*0.5; // _mainImageButton.layer.masksToBounds= YES; _mainImageButton.alpha = normalAlpha; [_mainImageButton addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside]; if (_animationColor) { [_mainImageButton addTarget:self action:@selector(mainBtnTouchDown) forControlEvents:UIControlEventTouchDown]; } [self addSubview:_mainImageButton]; // 增加拖动window的手势 _pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(locationChange:)]; _pan.delaysTouchesBegan = NO; [self addGestureRecognizer:_pan]; _tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(click:)]; [self addGestureRecognizer:_tap]; [self performSelector:@selector(justbegin) withObject:nil afterDelay:statusChangeDuration]; } return self; } 

至于怎么移动,怎么动画,直接看.h和.m文件如下:

JYCWindow.h###


#import <UIKit/UIKit.h>

typedef void(^CallTheService)(void); @interface JYCWindow : UIWindow //重要:所有图片都要是圆形的,程序里并没有自动处理成圆形 // warning: frame的长宽必须相等 - (instancetype)initWithFrame:(CGRect)frame mainImageName:(NSString*)name bgcolor:(UIColor *)bgcolor; // 长按雷达辐射效果 - (instancetype)initWithFrame:(CGRect)frame mainImageName:(NSString*)name bgcolor:(UIColor *)bgcolor animationColor:animationColor; // 显示(默认) - (void)showWindow; // 隐藏 - (void)dissmissWindow; @property (nonatomic,copy)CallTheService callService; @end 

JYCWindow.m###



#import "JYCWindow.h"
#define kk_WIDTH self.frame.size.width
#define kk_HEIGHT self.frame.size.height

#define kScreenWidth [[UIScreen mainScreen] bounds].size.width #define kScreenHeight [[UIScreen mainScreen] bounds].size.height #define animateDuration 0.3 //位置改变动画时间 #define showDuration 0.1 //展开动画时间 #define statusChangeDuration 3.0 //状态改变时间 #define normalAlpha 1.0 //正常状态时背景alpha值 #define sleepAlpha 0.5 //隐藏到边缘时的背景alpha值 #define myBorderWidth 1.0 //外框宽度 #define marginWith 5 //间隔 #define WZFlashInnerCircleInitialRaius 20 @interface JYCWindow () @property(nonatomic)NSInteger frameWidth; @property(nonatomic,strong)UIPanGestureRecognizer *pan; @property(nonatomic,strong)UITapGestureRecognizer *tap; @property(nonatomic,strong)UIButton *mainImageButton; @property(nonatomic,strong)UIColor *bgcolor; @property(nonatomic,strong)CAAnimationGroup *animationGroup; @property(nonatomic,strong)CAShapeLayer *circleShape; @property(nonatomic,strong)UIColor *animationColor; @end @implementation JYCWindow - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code } return self; } - (instancetype)initWithFrame:(CGRect)frame mainImageName:(NSString*)name bgcolor:(UIColor *)bgcolor{ return [self initWithFrame:frame mainImageName:name bgcolor:bgcolor animationColor:nil]; } - (instancetype)initWithFrame:(CGRect)frame mainImageName:(NSString*)name bgcolor:(UIColor *)bgcolor animationColor:animationColor { if(self = [super initWithFrame:frame]) { NSAssert(name != nil, @"mainImageName can't be nil !"); self.backgroundColor = [UIColor clearColor]; self.windowLevel = UIWindowLevelAlert + 1; //如果想在 alert 之上,则改成 + 2 self.rootViewController = [UIViewController new]; [self makeKeyAndVisible]; _bgcolor = bgcolor; _frameWidth = frame.size.width; _animationColor = animationColor; _mainImageButton = [UIButton buttonWithType:UIButtonTypeCustom]; [_mainImageButton setFrame:(CGRect){0, 0,frame.size.width, frame.size.height}]; [_mainImageButton setImage:[UIImage imageNamed:name] forState:UIControlStateNormal]; // _mainImageButton.layer.cornerRadius = frame.size.width*0.5; // _mainImageButton.layer.masksToBounds= YES; _mainImageButton.alpha = normalAlpha; [_mainImageButton addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside]; if (_animationColor) { [_mainImageButton addTarget:self action:@selector(mainBtnTouchDown) forControlEvents:UIControlEventTouchDown]; } [self addSubview:_mainImageButton]; // [self doBorderWidth:myBorderWidth color:nil cornerRadius:_frameWidth/2]; _pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(locationChange:)]; _pan.delaysTouchesBegan = NO; [self addGestureRecognizer:_pan]; _tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(click:)]; [self addGestureRecognizer:_tap]; [self performSelector:@selector(justbegin) withObject:nil afterDelay:statusChangeDuration]; } return self; } - (void)dissmissWindow{ self.hidden = YES; } - (void)showWindow{ self.hidden = NO; } - (void)justbegin{ [self performSelector:@selector(changeStatus) withObject:nil afterDelay:statusChangeDuration]; CGPoint panPoint = CGPointMake(kScreenWidth-80, kScreenHeight-150); [self changBoundsabovePanPoint:panPoint]; } - (void)changBoundsabovePanPoint:(CGPoint)panPoint{ if(panPoint.x <= kScreenWidth/2) { if(panPoint.y <= 40+kk_HEIGHT/2 && panPoint.x >= 20+kk_WIDTH/2) { [UIView animateWithDuration:animateDuration animations:^{ self.center = CGPointMake(panPoint.x, kk_HEIGHT/2); }]; } else if(panPoint.y >= kScreenHeight-kk_HEIGHT/2-40 && panPoint.x >= 20+kk_WIDTH/2) { [UIView animateWithDuration:animateDuration animations:^{ self.center = CGPointMake(panPoint.x, kScreenHeight-kk_HEIGHT/2); }]; } else if (panPoint.x < kk_WIDTH/2+20 && panPoint.y > kScreenHeight-kk_HEIGHT/2) { [UIView animateWithDuration:animateDuration animations:^{ self.center = CGPointMake(kk_WIDTH/2, kScreenHeight-kk_HEIGHT/2); }]; } else { CGFloat pointy = panPoint.y < kk_HEIGHT/2 ? kk_HEIGHT/2 :panPoint.y; [UIView animateWithDuration:animateDuration animations:^{ self.center = CGPointMake(kk_WIDTH/2, pointy); }]; } } else if(panPoint.x > kScreenWidth/2) { if(panPoint.y <= 40+kk_HEIGHT/2 && panPoint.x < kScreenWidth-kk_WIDTH/2-20 ) { [UIView animateWithDuration:animateDuration animations:^{ self.center = CGPointMake(panPoint.x, kk_HEIGHT/2); }]; } else if(panPoint.y >= kScreenHeight-40-kk_HEIGHT/2 && panPoint.x < kScreenWidth-kk_WIDTH/2-20) { [UIView animateWithDuration:animateDuration animations:^{ self.center = CGPointMake(panPoint.x, kScreenHeight-kk_HEIGHT/2); }]; } else if (panPoint.x > kScreenWidth-kk_WIDTH/2-20 && panPoint.y < kk_HEIGHT/2) { [UIView animateWithDuration:animateDuration animations:^{ self.center = CGPointMake(kScreenWidth-kk_WIDTH/2, kk_HEIGHT/2); }]; } else { CGFloat pointy = panPoint.y > kScreenHeight-kk_HEIGHT/2 ? kScreenHeight-kk_HEIGHT/2 :panPoint.y; [UIView animateWithDuration:animateDuration animations:^{ self.center = CGPointMake(kScreenWidth-kk_WIDTH/2, pointy); }]; } } } //改变位置 - (void)locationChange:(UIPanGestureRecognizer*)p { CGPoint panPoint = [p locationInView:[[UIApplication sharedApplication] keyWindow]]; if(p.state == UIGestureRecognizerStateBegan) { [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(changeStatus) object:nil]; _mainImageButton.alpha = normalAlpha; } if(p.state == UIGestureRecognizerStateChanged) { self.center = CGPointMake(panPoint.x, panPoint.y); } else if(p.state == UIGestureRecognizerStateEnded) { [self stopAnimation]; [self performSelector:@selector(changeStatus) withObject:nil afterDelay:statusChangeDuration]; [self changBoundsabovePanPoint:panPoint]; } } //点击事件 - (void)click:(UITapGestureRecognizer*)p { [self stopAnimation]; _mainImageButton.alpha = normalAlpha; 

转载于:https://www.cnblogs.com/sundaysgarden/p/9241697.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值