6、悬浮窗的封装

2017-03-12  本文已影响0人  紅寶石

因为之前做游戏SDK的开发,主要是集成登录、注册、充值以及最重要的悬浮窗的制作;封装成一个类,方便自己以后使用😄;
我的Demo地址:https://github.com/hongbaoshi/LZWFloatWindow
参考地址:https://github.com/search?utf8=%E2%9C%93&q=DYYFloatWindow

创建引入:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //防止与主window冲突,延迟执行;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(),^{
        [self creatFloatWindow];
    });
    
}



-(void)creatFloatWindow
{
    _change_floatWindow = [[LZWFloatWindow alloc] initWithFrame:CGRectMake(100, 100, 50,50) andWithMainImageName:@"z" andWithTitleDic:@{@"ddd":@"用户中心",@"eee":@"退出登录",@"fff":@"客服中心"} andWithStartBtnTag:100 andWithAnimationColor:[UIColor purpleColor]];
    
    _change_floatWindow.backBlock = ^(NSInteger tag){
        NSLog(@"点击第%ld个按钮",tag);
    };
}


具体实现:

#import <UIKit/UIKit.h>

typedef void(^MyBlock)(NSInteger tag);

@interface LZWFloatWindow : UIWindow

@property(nonatomic,strong)MyBlock backBlock;

-(id)initWithFrame:(CGRect)frame andWithMainImageName:(NSString *)bgName andWithTitleDic:(NSDictionary *)titleDic andWithStartBtnTag:(int)startTag andWithAnimationColor:(UIColor *)color;

@end


#import "LZWFloatWindow.h"
#import <CoreMotion/CoreMotion.h>

#define LZW_WIDTH [[UIApplication sharedApplication].windows firstObject].bounds.size.width
#define WZFlashInnerCircleInitialRaius  20

@interface LZWFloatWindow()

@property(nonatomic,strong)UIButton *mainBtn;
@property(nonatomic,assign)BOOL isShowDetail;//是否展开悬浮窗,默认不展开;
@property(nonatomic,assign)CGRect startFrame;//悬浮窗初始显示位置
@property(nonatomic,assign)NSInteger btnWidth;//各个按钮的宽;

@property(nonatomic,strong)UIView *contentView;//点击btn展示的详情界面;
@property(nonatomic,strong)NSDictionary *titleDic;//保存详情页面标题的字典;
@property(nonatomic,assign)int btnTag;//详情每个按钮的tag值;
@property(nonatomic,strong)UIPanGestureRecognizer *movePan;//悬浮窗移动手势
@property(nonatomic,strong)CMMotionManager *motionManager;//添加重力感应器
@property(assign, nonatomic) NSTimeInterval gyroUpdateInterval;
@property(nonatomic,assign)double accZ; //z轴方向的偏移量;
@property(nonatomic,assign)BOOL isHide;

@property(nonatomic,strong)CAAnimationGroup *animationGroup;
@property(nonatomic,strong)CAShapeLayer *circleShape;
@property(nonatomic,strong)UIColor *animationColor;

@end
@implementation LZWFloatWindow

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        
    }
    return self;
}

-(id)initWithFrame:(CGRect)frame andWithMainImageName:(NSString *)bgName andWithTitleDic:(NSDictionary *)titleDic andWithStartBtnTag:(int)startTag andWithAnimationColor:(UIColor *)color;
{
    if (self = [super initWithFrame:frame])
    {
        //初始化属性
        _startFrame = frame;
        _btnWidth = frame.size.width;
        _titleDic = titleDic;
        _btnTag = startTag;
        _animationColor = color;
        
        _isShowDetail = NO;
        _isHide = NO;
        
        //UI
        self.backgroundColor = [UIColor clearColor];
        self.rootViewController = [UIViewController new];
        self.rootViewController.view.backgroundColor = [UIColor blackColor];
        self.windowLevel = UIWindowLevelAlert + 1;
        self.alpha = 0.8;
        self.layer.cornerRadius = 26;
        self.layer.masksToBounds = YES;
        self.layer.borderColor = [UIColor colorWithRed:0.94 green:0.61 blue:0.30 alpha:1.00].CGColor;
        self.layer.borderWidth = 1;
        [self makeKeyAndVisible];
        
        _mainBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _mainBtn.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
        [_mainBtn setImage:[UIImage imageNamed:bgName] forState:UIControlStateNormal];
        [_mainBtn addTarget:self action:@selector(mainBtnClick) forControlEvents:UIControlEventTouchUpInside];
        if (_animationColor) {
            //5---添加长按雷达效果;
//            [_mainBtn addTarget:self action:@selector(mainBtnTouchDown) forControlEvents:UIControlEventTouchDown];
        }
        [self.rootViewController.view addSubview:_mainBtn];
        
        _contentView = [UIView new];
        _contentView.backgroundColor = [UIColor blackColor];
        _contentView.frame = CGRectMake(_btnWidth, 0, _titleDic.count*(_btnWidth+5), _btnWidth);
        [self.rootViewController.view addSubview:_contentView];

       //1---给contentView添加按钮
        [self setContentViewBtns];
        
        //2---添加手势
        _movePan = [[UIPanGestureRecognizer alloc] init];
        [_movePan addTarget:self action:@selector(locationChange:)];
        _movePan.delaysTouchesBegan = YES;
        [self addGestureRecognizer:_movePan];
        
        //3---设备旋转的时候收回详情界面
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
        
        //4---添加翻转隐藏悬浮窗;
        //开启陀螺仪感应器;
        //重力感应的设置
        [self accelerotionDataMethod];
        
    }
    return self;
}


-(void)mainBtnClick
{
    _isShowDetail = !_isShowDetail;
    
    if (self.center.x == LZW_WIDTH+5)
    {
        _mainBtn.frame = CGRectMake(0, 0, 50, 50);
        [_mainBtn setImage:[UIImage imageNamed:@"z"] forState:UIControlStateNormal];
        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, _btnWidth+(5+_btnWidth)*_titleDic.count, _btnWidth);
        self.center = CGPointMake(LZW_WIDTH-(_btnWidth+(5+_btnWidth)*_titleDic.count)/2, self.center.y);
        return;
    }
    
    
    if (_isShowDetail)
    {
        [UIView animateWithDuration:0.5 animations:^{
            self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, _btnWidth+(5+_btnWidth)*_titleDic.count, _btnWidth);
        }];
    }else
    {
        [UIView animateWithDuration:0.5 animations:^{
            self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, _btnWidth, _btnWidth);
        }];
    }
    
}

-(void)setContentViewBtns
{
    int i = 0;
    for (NSString *key in _titleDic)
    {
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        btn.frame = CGRectMake(i*_btnWidth, 0, _btnWidth, _btnWidth);
        [btn setTitle:_titleDic[key] forState:UIControlStateNormal];
        [btn setImage:[UIImage imageNamed:key] forState:UIControlStateNormal];
        btn.tag = _btnTag;
        // 则默认image在左,title在右
        // 改成image在上,title在下
        btn.titleEdgeInsets = UIEdgeInsetsMake(self.btnWidth/2 , -[UIImage imageNamed:key].size.width, 0.0, 0.0);
        btn.imageEdgeInsets = UIEdgeInsetsMake(2.0, 8.0, 16.0, -
                                                  btn.titleLabel.bounds.size.width + 8);
        btn.titleLabel.font = [UIFont systemFontOfSize: self.btnWidth/5];
        [btn addTarget:self action:@selector(itemsClick:) forControlEvents:UIControlEventTouchUpInside];
        [_contentView addSubview:btn];
        i++;
        _btnTag++;
    }
}


-(void)locationChange:(UIPanGestureRecognizer *)p
{
    //获取停止的位置坐标
    CGPoint panPoint = [p locationInView:[[UIApplication sharedApplication].windows firstObject]];
    if(p.state == UIGestureRecognizerStateBegan)
    {
        
    }
    else if (p.state == UIGestureRecognizerStateEnded)
    {
        CGPoint velocity = [p velocityInView:[[UIApplication sharedApplication].windows firstObject]];
        CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
        CGFloat slideMult = magnitude / 300;
        float slideFactor = 0.1 * slideMult;
//        NSLog(@"%f  %f  %f  %f  %f",panPoint.x,panPoint.y,velocity.x,velocity.y,slideMult);
        CGPoint finalPoint = CGPointMake(p.view.center.x + (velocity.x * slideFactor),
                                         p.view.center.y + (velocity.y * slideFactor));
        
        if (!_isShowDetail)
        {
            //限制下最小、最大坐标,防止停靠在角落;
            finalPoint.x = MIN(MAX(finalPoint.x, 25), [[UIApplication sharedApplication].windows firstObject].bounds.size.width-25);
            finalPoint.y = MIN(MAX(finalPoint.y, 70), [[UIApplication sharedApplication].windows firstObject].bounds.size.height-70);
            
            [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
                p.view.center = finalPoint;
                if (self.center.x == 25)
                {
                    [self performSelector:@selector(yinCanLeftFloat) withObject:nil afterDelay:0.3];
                    
                    
                }else if(self.center.x == [[UIApplication sharedApplication].windows firstObject].bounds.size.width-25)
                {
                    [self performSelector:@selector(yinCanRightFloat) withObject:nil afterDelay:0.3];
                }
                
            } completion:nil];
        }else
        {
            //限制下最小、最大坐标,防止停靠在角落;
            finalPoint.x = MIN(MAX(finalPoint.x, (_btnWidth+(5+_btnWidth)*_titleDic.count)/2), [[UIApplication sharedApplication].windows firstObject].bounds.size.width-(_btnWidth+(5+_btnWidth)*_titleDic.count)/2);
            finalPoint.y = MIN(MAX(finalPoint.y, 70), [[UIApplication sharedApplication].windows firstObject].bounds.size.height-70);
            [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
                p.view.center = finalPoint;
            } completion:nil];
        }
    }
    else if(p.state == UIGestureRecognizerStateChanged)
    {
        self.center = CGPointMake(panPoint.x, panPoint.y);
        
        if (self.center.x >25)
        {
            _mainBtn.userInteractionEnabled = YES;
            _mainBtn.frame = CGRectMake(0, 0, 50, 50);
            [_mainBtn setImage:[UIImage imageNamed:@"z"] forState:UIControlStateNormal];
            
        }else if(self.center.x < [[UIApplication sharedApplication].windows firstObject].bounds.size.width-25)
        {
            _mainBtn.userInteractionEnabled = YES;
            _mainBtn.frame = CGRectMake(0, 0, 50, 50);
            [_mainBtn setImage:[UIImage imageNamed:@"z"] forState:UIControlStateNormal];
        }
    }
}

-(void)yinCanLeftFloat
{
    [UIView animateWithDuration:0.6 animations:^{
        self.center = CGPointMake(-50, self.center.y);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.5 animations:^{
            self.center = CGPointMake(-5, self.center.y);
            _mainBtn.frame = CGRectMake(30, 0, 20, 50);
            [_mainBtn setImage:[UIImage imageNamed:@"left_float.png"] forState:UIControlStateNormal];
        }];
    }];
}

-(void)yinCanRightFloat
{
    [UIView animateWithDuration:0.6 animations:^{
        self.center = CGPointMake([[UIApplication sharedApplication].windows firstObject].bounds.size.width+50, self.center.y);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.5 animations:^{
            self.center = CGPointMake([[UIApplication sharedApplication].windows firstObject].bounds.size.width+5, self.center.y);
            _mainBtn.frame = CGRectMake(0, 0, 20, 50);
            [_mainBtn setImage:[UIImage imageNamed:@"right_float.png"] forState:UIControlStateNormal];
        }];
    }];
}


-(void)orientChange:(NSNotification *)notification
{
    self.frame = CGRectMake(self.startFrame.origin.x, self.startFrame.origin.y, _btnWidth, _btnWidth);
}

-(void)accelerotionDataMethod
{
    self.motionManager = [[CMMotionManager alloc] init];
    self.gyroUpdateInterval = 0.2;
    self.motionManager.accelerometerUpdateInterval = self.gyroUpdateInterval;
    __weak LZWFloatWindow *weakself = self;
    [self.motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue currentQueue]
                                             withHandler:^(CMAccelerometerData  *accelerometerData, NSError *error) {
                                                 [weakself outputAccelertionData:accelerometerData.acceleration];
                                                 if(error){
                                                     NSLog(@"%@", error);
                                                 }
                                             }];
    [self.motionManager startGyroUpdates];
}

-(void)outputAccelertionData:(CMAcceleration)acceleration
{
    
    self.accZ = acceleration.z;
    
    if (self.accZ >= 0.2)
    {
        [self.motionManager stopAccelerometerUpdates];
        
        _isHide = !_isHide;
        self.hidden = _isHide;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(),^{
            [self accelerotionDataMethod];
        });
    }
    
}



-(void)itemsClick:(id)sender
{
    UIButton *btn = (UIButton *)sender;
    self.backBlock(btn.tag);
}



@end


3249841-b4702615b8a7d618.jpg
上一篇下一篇

猜你喜欢

热点阅读