我正在尝试找出如何使用非公开/私有api查找最顶层的视图,有没有办法(iOS 7.1.2)?
修改
也许我不清楚, 无论现在哪个应用程序处于活动状态(Facebook,WhatsApp,游戏,锁屏,日历等),我都希望得到最顶层的视图。
答案 0 :(得分:6)
如果我理解正确,您希望在另一个应用程序窗口的顶部显示UIView。在应用程序沙箱中,您只能访问自己的应用程序窗口。然而,越狱将允许你这样做,但这并不简单。
为了在应用程序之上显示视图,您有三种选择。您选择哪个选项取决于您要做的事情。
如果您选择使用此路由,则代码将在每个第三方应用程序中运行。这允许您修改应用程序的视图层次结构以显示您自己的窗口,甚至可以修改现有窗口。由于您的代码在应用程序中运行,您只需调用:
即可获得密钥窗口[[UIApplication sharedApplication] keyWindow]
如果选择此选项,则无论打开哪个应用程序,您的代码都将运行。通过获取主窗口,您可以显示任何内容的UI,包括系统警报。我在rpendleton/tutorials/so-26032688向GitHub发布了一个这样的例子。该示例在用户将手机从静音状态中随时显示警报。检索SpringBoard
窗口的代码是:
[[NSClassFromString(@"SBUIController") sharedInstance] window]
第三个选项,也是您可能最终使用的选项,是选项1和2的组合。在这种情况下,您将代码注入第三方应用程序,然后与SpringBoard通信决定需要做什么。通常,您的应用程序将与SpringBoard通信,然后SpringBoard可以将该信息转发到所需的应用程序。您可以直接在您的应用程序和第三方应用程序之间进行通信,但我没有尝试过。
为了在您的应用程序与SpringBoard
/其他第三方应用程序之间进行通信,您需要使用消息传递系统。一种简单的方法是通过一个名为RocketBootstrap的开源库。
左侧的屏幕截图来自我在GitHub上发布的示例,右侧的屏幕截图来自我的一个调整AppScan。虽然我在两者中都有提醒,但你可以显示你想要的任何视图。
答案 1 :(得分:0)
尝试像这样获取AppDelegate的窗口
UIWindow *window = ((AppDelegate*)[UIApplication sharedApplication].delegate).window;
然后访问窗口的最后一个对象
[[window subviews] objectAtIndex:0];
或者像这样
[[window subviews]lastObject];
如果你想添加子视图
[[[window subviews] objectAtIndex:0] addSubview:view];
答案 2 :(得分:0)
阅读问题和评论这是你正在寻找的...我想,不是我看到的最详细的问题:
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.rootViewController = self;
window.windowLevel = [[UIApplication sharedApplication] keyWindow].windowLevel + 1;
[window makeKeyAndVisible];
您希望将其用作顶部所需的视图控制器的一部分。
答案 3 :(得分:0)
你的问题不完全清楚,你能解释一下你为什么需要这样做吗? 顺便说一句,你最需要的是关键窗口,如文档中所述:
键窗口是指定接收键盘的窗口 其他非触摸相关事件。一次只能有一个窗口 关键窗口。
您可以做的是询问应用程序当前关键窗口:
NSArray * array = [[UIApplication sharedApplication] windows];
迭代该数组以找到关键窗口,然后检查其子视图:
UIView * topView = [[window subviews]lastObject]
如果您正在寻找一种模拟警报视图的方法,您应该创建自己的UIWindow,然后添加您的视图控制器来处理"警告"作为rootViewController
并使其成为"键和可见"。
这样的事情:
UIWindow *alertWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
alertWindow.rootViewController = [[AlertViewController alloc] initWithXibNamed:@"AlertXib"];
alertWindow.windowLevel = UIWindowLevelAlert;
[alertWindow makeKeyAndVisible];
当您想要解除时,只需将rootViewController设置为nil并使窗口隐藏
使用根视图控制器方法有助于避免混乱旋转校正。即使在iOS8中旋转。
我找到了一个很好的参考here。