多页面悬停控件和如何获得多UIWindow的页面UIWindow

简介: 多页面悬停控件和如何获得多UIWindow的页面UIWindow

若你的app需要悬停一个控件在绝大多数页面上,那么最后的解决方案是:把这个控件做成一个UIWindow,并且设置_statusWindow.windowLevel = UIWindowLevelStatusBar + 1;。注意:这个控件是显示在所有页面中的,除非页面掉用了它的隐藏函数([[PPPlayNoticeView currentNotice] animationHide];),不然它在app那个页面都显示。不过它依赖于app(app就是一个单进程应用,不可能存在多个进程。WKWebView是我见到的iOS唯一一个进程组件,不过通过它起的进程在iOS操作系统中,它虽然和app有通信机制,收到那个进程的数据,但是不受app管辖,app收到它的数据也可能是不实时的,像cookie数据),不会显示在其它app页面中,这个安卓是不一样的。UIAlertView弹窗是系统级别的,可以不依赖于app存在,但是它出来后,不让它消失什么也干不了。不是我们需要控件。

那新问题来了,若这个跨页面的控件显示时,你使用在keywindow上增加图层,可能时增加到这个控件UIWindow的keywindow上。结果是你那个图层显示不出来,只看到一个带透明度的图层。那如何找到当前页面的UIWindow呢?使用下面函数就能找到。

-(UIWindow *)getLevelNormalWindwow
{
    NSArray *windows = [[UIApplication sharedApplication] windows];

    for(UIWindow * tmpWin in windows)
    {
        if (tmpWin.windowLevel == UIWindowLevelNormal)
        {
            UIViewController *result = nil;
            UIView *frontView = [[tmpWin subviews] objectAtSafeIndex:0];
            id nextResponder = [frontView nextResponder];
            
            if ([nextResponder isKindOfClass:[UIViewController class]])
                result = nextResponder;
            else
                result = tmpWin.rootViewController;
            
            NSArray *cv = [result childViewControllers];
            NSLog(@"%@",cv);
            if(cv && [cv isKindOfClass:[NSArray class]] && cv.count > 0)
            {
                return tmpWin;
            }
        }
    }
    return nil;
}

日志打印:

2020-06-18 13:47:08.898734+0800 PinkPig[5900:133486] (
    "<BITBaseTabBarController: 0x7fafb2e154e0>",
    "<PPRoomViewController: 0x7fafb4816800>"
)

当然判断if (tmpWin.windowLevel == UIWindowLevelNormal)就够了,下面多的if(cv && [cv isKindOfClass:[NSArray class]] && cv.count > 0)只是以防万一。你新建的UIWindow不会是UIWindowLevelNormal,不然不知道那个页面在上面呢!,当然你建立rootViewController所在的window时,设置了非UIWindowLevelNormal的值那个判断也要变成你设置成的windowLevel值(就是修改这句if (tmpWin.windowLevel == UIWindowLevelNormal)),不设置windowLevel是默认值UIWindowLevelNormal。

一般是在AppDelegate里设置UIWindow的,如:

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:LoginVC];
    self.window.rootViewController = nav;
    [self.window makeKeyAndVisible];
```。
当然我采用的组件化,是在系统模块里设置self.tabBarController的。
具体使用代码:

[self addSubview:self.headDetailView];

当然你可以把这个函数放在静态类或单例中,在那里都能调用该函数,如在调用单例的该函数`[[[UIApplication sharedApplication] keyWindow] addSubview:self.headDetailView];`。

目录
相关文章
|
存储 缓存 网络协议
Linux系统之ARP命令的基本使用
【7月更文挑战第2天】Linux系统之ARP命令的基本使用
885 3
Linux 操作系统
在 Linux 中,UID(用户 ID)是标识用户身份的重要概念。UID 唯一标识每个用户,通过 UID 可区分不同用户类别:UID 0 为超级用户,1-999 为系统用户,1000 及以上为普通用户。因此,正确选项为:UID 标识用户、可区分用户类别、普通用户 UID 大于 1000。
|
存储 文字识别 数据可视化
让你的电脑变得与众不同的冷门小工具
本文推荐了5款冷门但功能强大的小工具:1. MiniBin,轻量级回收站管理工具;2. AltairSimLab,多物理场仿真平台;3. 燃精灵,微信空号检测软件;4. IrfanView,经典图像查看器;5. Folder Size View,磁盘空间分析工具。这些软件体积小巧,功能出色,可大幅提升工作效率。
397 4
|
5G 网络架构 UED
网速只拼Mbps?解码网速真相的五大关键因素
Mbps(兆比特每秒)是衡量数据传输速度的单位,表示每秒传输的百万比特数。它是评估网络性能的核心指标,广泛应用于家用宽带、移动网络和企业级网络中。Mbps 数值越高,理论上数据传输越快,但实际体验还受网络拥塞、丢包率和信号强度等因素影响。例如,在网络高峰时段或信号较弱的地方,即使Mbps数值高,也可能出现卡顿。5G和光纤技术显著提升了Mbps速率,但仍需考虑硬件设备如路由器和网卡的性能瓶颈。理解Mbps及其影响因素,有助于用户选择合适的网络服务并优化网络体验。
1328 1
|
前端开发 JavaScript 开发者
React 事件处理机制详解
【10月更文挑战第23天】本文介绍了 React 的事件处理机制,包括事件绑定、事件对象、常见问题及解决方案。通过基础概念和代码示例,详细讲解了如何处理 `this` 绑定、性能优化、阻止默认行为和事件委托等问题,帮助开发者编写高效、可维护的 React 应用程序。
659 4
对excel读写的三个模块,xlsxwriter最牛,xlwt , xlrd,openpyxl
对excel读写的三个模块,xlsxwriter最牛,xlwt , xlrd,openpyxl
|
机器学习/深度学习 算法 Java
计算机视觉——opencv快速入门(一) opencv的介绍与安装
OpenCV是开源计算机视觉库,支持C++, Python, Java等,用于图像处理、视频分析等。建议使用较早版本如3.4.3,因高版本部分算法需付费。通过Anaconda创建Python虚拟环境来安装,选择合适的Python和OpenCV版本。激活环境后,用`pip`安装`opencv-python`。基本环境配置完成后,通过显示图像的Python代码测试安装是否成功。
计算机视觉——opencv快速入门(一) opencv的介绍与安装
|
存储 Linux Shell
使用Git LFS托管大文件
使用Git LFS托管大文件
|
存储 数据可视化 前端开发
CodeWave智能开发平台--03--目标:应用创建--08联系人管理
CodeWave智能开发平台--03--目标:应用创建--08联系人管理
|
存储 运维 Cloud Native
MinIO与传统的对象存储系统相比有以下几个不同之处
MinIO与传统的对象存储系统相比有以下几个不同之处
729 0