iOS中全局悬浮按钮,类似IPhone中的AssistiveTouch (可以替换为视频悬浮窗口)

本文介绍了一个改进后的iOS悬浮窗解决方案,解决了位置不可调整、页面切换失效及运行时偶发崩溃的问题。通过创建自定义 UIWindow 子类并利用 UIPanGestureRecognizer 实现了悬浮窗位置调整功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前提:当时看到别人写过这个类似AssistiveTouch的demo,但是有问题,第一改变不了位置、第二切换页面后无法使用、第三运行时偶尔会崩溃。然后自己就去度娘、论坛中都查了一些资料,然后结合起来写了这么一个demo。
思路:实现全局 需要在 AppDelegate.m 文件中 didFinishLaunchingWithOptions 方法里面实现
1、新建一个 继承于 UIWindow 的类 AssistiveTouch

//在 AssistiveTouch.h 文件中代码

#import <UIKit/UIKit.h>

@interface AssistiveView : UIWindow

{

    UIButton *_button;

}


-(id) initWithFrame:(CGRect)frame;


@end


//在 AssistiveTouch.m 文件中代码

#import "AssistiveView.h"


@implementation AssistiveView


/*

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect {

    // Drawing code

}

*/

-(id)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    

    if (self) {

        self.backgroundColor = [UIColor clearColor];

        self.windowLevel = UIWindowLevelAlert + 1;

        //这句话很重要

        [self makeKeyAndVisible];

        

        _button = [UIButton buttonWithType:UIButtonTypeCustom];

        _button.backgroundColor = [UIColor grayColor];

        _button.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);

        _button.layer.cornerRadius = frame.size.width/2;

        [_button addTarget:self action:@selector(choose) forControlEvents:UIControlEventTouchUpInside];

        [self addSubview:_button];

        

        //放一个拖动手势,用来改变控件的位置

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

        [_button addGestureRecognizer:pan];

    }

    return self;

}


//按钮事件

-(void)choose

{

    NSLog(@"悬浮窗");

}

//手势事件 -- 改变位置

-(void)changePostion:(UIPanGestureRecognizer *)pan

{

    CGPoint point = [pan translationInView:self];

    

    CGFloat width = [UIScreen mainScreen].bounds.size.width;

    CGFloat height = [UIScreen mainScreen].bounds.size.height;

    

    CGRect originalFrame = self.frame;

    if (originalFrame.origin.x >= 0 && originalFrame.origin.x+originalFrame.size.width <= width) {

        originalFrame.origin.x += point.x;

    }

    if (originalFrame.origin.y >= 0 && originalFrame.origin.y+originalFrame.size.height <= height) {

        originalFrame.origin.y += point.y;

    }

    self.frame = originalFrame;

    [pan setTranslation:CGPointZero inView:self];

    

    if (pan.state == UIGestureRecognizerStateBegan) {

        _button.enabled = NO;

    }else if (pan.state == UIGestureRecognizerStateChanged){

        

    } else {

        

        CGRect frame = self.frame;

        //记录是否越界

        BOOL isOver = NO;

        

        if (frame.origin.x < 0) {

            frame.origin.x = 0;

            isOver = YES;

        } else if (frame.origin.x+frame.size.width > width) {

            frame.origin.x = width - frame.size.width;

            isOver = YES;

        }

        

        if (frame.origin.y < 0) {

            frame.origin.y = 0;

            isOver = YES;

        } else if (frame.origin.y+frame.size.height > height) {

            frame.origin.y = height - frame.size.height;

            isOver = YES;

        }

        if (isOver) {

            [UIView animateWithDuration:0.3 animations:^{

                self.frame = frame;

            }];

        }

        _button.enabled = YES;

    }

}


//在 AppDelegate中的代码

#import "AppDelegate.h"

#import "AssistiveView.h"


@interface AppDelegate ()

{

    //悬浮框

    AssistiveView * _Win;

}


@end


@implementation AppDelegate


// 设置自定义悬浮框坐标

-(void)setNew

{

    _Win = [[AssistiveView alloc] initWithFrame:CGRectMake(0, 100, 60, 60)];

}


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Override point for customization after application launch.

    

    // 这句话很重要,要先将rootview加载完成之后在显示悬浮框,如没有这句话,将可能造成程序崩溃

    [self performSelector:@selector(setNew) withObject:nil afterDelay:3];

    

    [self.window makeKeyAndVisible];


    

    return YES;

}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值