iOS悬浮球的实现

1,025 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情

背景

  • 很多游戏SDK里面会有一个一直悬浮的悬浮球,这个功能也基本成了游戏SDK里面必备的一个组件

需求

  • 在所有界面上面,界面跳转,转场都不会遮住这个球。让用户随时可以点击到。但是不能影响到用户体验游戏(或APP),所以需要靠边吸附

解决思路

  • UIview分层级windowLevel,只需要把这个视图的层级调成最高的,这样不管到哪个控制器,哪个界面 都可以实现在最上层
  • 用户点击或者触摸可以弹出交互界面:
    • 解决方案大概有两种:
      • 1 获取当前视图控制器,把弹出来的交互视图添加到该控制器上。因为是最后添加的,所以不用考虑会被其他视图遮挡
      • 2 同样的原理给视图层级设置成最高,让他在最上面,这样不用每次关闭的时候就销毁掉,出现的时候再添加到当前控制器上
  • 所有的UIview都需要依赖父视图,才能展现出来。那么就需要一个不会销毁 一直曾在的视图作为载体。keywindow最合适了

+(**void**)showFloatingball
{
    dispatch_async(dispatch_get_main_queue(), ^{
        **if** ([HGHShowBall shareInstance].isaready&&[HGHShowBall shareInstance].floatBall.hidden == **NO**) {

            **return**;

        }

        CGRect frame = CGRectMake(0, 30, 50, 50);

        [HGHShowBall shareInstance].floatBall = [[HGHFloatingBall alloc]initWithFrame:frame];

        [HGHShowBall shareInstance].floatBall.hidden = **NO**;

        [[UIApplication sharedApplication].keyWindow addSubview:[HGHShowBall shareInstance].floatBall];

        [HGHShowBall shareInstance].isaready = **YES**;
    });
}
  • 这样视图就可以显示在最上面了,剩下的靠边吸附,拖动手势,tap手势往上加就行了
-(**instancetype**)initWithFrame:(CGRect)frame

{

    **if** (**self**=[**super** initWithFrame:frame]) {

        **self**.frame = frame;

        **self**.backgroundColor = [UIColor clearColor];

//        self.windowLevel =  UIWindowLevelAlert+1;

        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:**self** action: **@selector**(gesturPan:)];

        [**self** addGestureRecognizer:pan];

        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:**self** action: **@selector**(gesturTap:)];

        [**self** addGestureRecognizer:tap];

        **self**.imageV = [[UIImageView alloc]initWithFrame:**self**.bounds];

        [**self** addSubview:**self**.imageV];

        [**self** addgifImageV];

        NSString *imageName = @"float_icon";

            **self**.imageV.image = [UIImage imageNamed:imageName];

        **self**.isHalfHidden = **NO**;

        [**self** creatTimer];

    }
    **return** **self**;

}
  • 手势拖动后 靠边吸附
-(**void**)gesturPan:(UIPanGestureRecognizer *)sender

{

    UIView *testView = sender.view;

    CGRect frame = **self**.imageV.frame;

    CGFloat scale = [AWSDKConfigManager shareinstance].icon_scale / 100.0;

    frame.size.width = 50 * scale;

    **self**.imageV.frame = frame;

    **self**.imageV.alpha = 1.0;

    

    NSString *imageName = @"AWSDK.bundle/aw_float_icon";

    imageName = [NSString stringWithFormat:@"%@_%@.png",imageName,[AWSDKConfigManager shareinstance].float_ball_type];

    **if** ([AWSDKConfigManager shareinstance].isMiddle) {

        [**self**.imageV setImage:[AWSDKConfigManager shareinstance].middleImage];

    }**else**{

        **self**.imageV.image = [UIImage imageNamed:imageName];

    }

    **self**.gifimageV.frame = frame;

    

    NSString *imageNamegif = @"AWSDK.bundle/aw_float_icon_effects";

    imageNamegif = [NSString stringWithFormat:@"%@_%@.gif",imageNamegif,[AWSDKConfigManager shareinstance].float_ball_type];

    [**self** setgifviewWithimage:imageNamegif];

    CGPoint startPoint;


    **if** (sender.state == UIGestureRecognizerStateBegan) {

        AWLog(@"start point");

        startPoint = [sender locationInView:sender.view];
         originPoint = [sender locationInView:[UIApplication sharedApplication].keyWindow];

        AWLog(@"startPoint=%f,%f,originPoint=%f,%f",startPoint.x,startPoint.y,originPoint.x,originPoint.y);

    }**else** **if** (sender.state == UIGestureRecognizerStateChanged){

        CGPoint newPoint = [sender locationInView:sender.view];

        CGFloat deltaX = newPoint.x-startPoint.x;

        CGFloat deltaY = newPoint.y-startPoint.y;

        testView.center = CGPointMake(testView.center.x+deltaX, testView.center.y+deltaY);

        originPoint = [sender locationInView:[UIApplication sharedApplication].keyWindow];


    }**else** **if** (sender.state == UIGestureRecognizerStateEnded){

        **if** (originPoint.x >= [UIScreen mainScreen].bounds.size.width - testView.frame.size.width/2) {

            originPoint.x = [UIScreen mainScreen].bounds.size.width - testView.frame.size.width/2;

            testView.center = originPoint;

            [**self** halfHidden];

            **return**;

        }

        **if** (originPoint.x-testView.frame.size.width/2<=0) {

            originPoint.x = testView.frame.size.width/2;

            testView.center = originPoint;

            [**self** halfHidden];

            **return**;

        }

        **if** (IphoneX&&[AWTools DeviceOrientation]==2&&[AWTools isInLiuhai:originPoint.y-testView.frame.size.height/2]) {

            **if** (originPoint.x-testView.frame.size.width/2-30<=0) {

                originPoint.x = testView.frame.size.width/2+30;

                testView.center = originPoint;

                [**self** halfHidden];

                **return**;

            }

        }

        **if** (IphoneX&&[AWTools DeviceOrientation]==1&&[AWTools isInLiuhai:originPoint.y-testView.frame.size.height/2]) {

            **if** (originPoint.x >= [UIScreen mainScreen].bounds.size.width - testView.frame.size.width/2-30) {

                originPoint.x = [UIScreen mainScreen].bounds.size.width - testView.frame.size.width/2-30;

                testView.center = originPoint;

                [**self** halfHidden];

                **return**;

            }

        }

        

        [UIView animateWithDuration:0.3 animations:^{

            **if** (originPoint.x-testView.frame.size.width/2<=0) {

                originPoint.x = testView.frame.size.width/2 +10;

            }

            **if** (originPoint.y - testView.frame.size.height/2  <=20) {

                originPoint.y = testView.frame.size.height/2 +20;

            }


            **if** (originPoint.x >= [UIScreen mainScreen].bounds.size.width - testView.frame.size.width/2) {

                originPoint.x = [UIScreen mainScreen].bounds.size.width - testView.frame.size.width/2;

            }

            **if** (originPoint.y >=[UIScreen mainScreen].bounds.size.height - testView.frame.size.height/2-11) {

                originPoint.y = [UIScreen mainScreen].bounds.size.height - testView.frame.size.height/2 - 10;

            }

            

            **if** (originPoint.x>[UIScreen mainScreen].bounds.size.width/2) {

                **if** (IphoneX&&[AWTools DeviceOrientation]==1&&[AWTools isInLiuhai:originPoint.y-testView.frame.size.height/2])//刘海在右

                {

                    originPoint.x = [UIScreen mainScreen].bounds.size.width - testView.frame.size.width/2 -30;//刘海高度34

                }**else**{

                    originPoint.x = [UIScreen mainScreen].bounds.size.width - testView.frame.size.width/2;

                }

                

            }**else**{

                **if** (IphoneX&&[AWTools DeviceOrientation]==2&&[AWTools isInLiuhai:originPoint.y-testView.frame.size.height/2]){

                    originPoint.x = testView.frame.size.width/2+30;

                }**else**{

                    originPoint.x = testView.frame.size.width/2;

                }
            }


            testView.center = originPoint;

            

        }];

        [**self** endPoint];

    }

}

很多年前写的东西了,培养一下写博客的乐趣就先拿出来分享吧