美文网首页
6、悬浮窗的封装

6、悬浮窗的封装

作者: 紅寶石 | 来源:发表于2017-03-12 12:48 被阅读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

    相关文章

      网友评论

          本文标题:6、悬浮窗的封装

          本文链接:https://www.haomeiwen.com/subject/numtnttx.html