将 UIView 或 UIWindow 放在状态栏上方

Posted

技术标签:

【中文标题】将 UIView 或 UIWindow 放在状态栏上方【英文标题】:Putting a UIView or UIWindow above Statusbar 【发布时间】:2011-05-14 05:11:18 【问题描述】:

我的目标是在我的 iPhone 应用顶部的状态栏上方绘制一个不可见的按钮(尺寸 320*20 像素)。

无论我尝试什么,都有问题:

    例如,我尝试创建一个新视图。当我想将视图放在我的应用顶部时,它总是消失在状态栏后面而不是在它前面!

    我在 *** 上发现了另一个好主意: Add UIView Above All Other Views, Including StatusBar 即使不推荐使用第二个 UIWindow,我也尝试实现它。它按我的意愿工作,直到我注意到一个问题:键盘在需要时不再出现(例如在单击文本框时)!

我该如何解决这个问题?还是有更好的方法来解决我的问题?这是我创建第二个窗口的代码:

// Create window
statusWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0,0,320,20)];
statusWindow.windowLevel = UIWindowLevelStatusBar;
[statusWindow makeKeyAndVisible];

// Create statusBarButton
statusBarButton = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect buttonFrame2 = statusBarButton.frame;
buttonFrame2.size = CGSizeMake(320,20);
statusBarButton.frame = buttonFrame2;
[statusBarButton addTarget:self action:@selector(goTop) forControlEvents:UIControlEventTouchUpInside]; 

// Place button into the new window
[statusWindow addSubview:statusBarButton];

【问题讨论】:

【参考方案1】:

在 AppDelegate 文件中

self.window.windowLevel = UIWindowLevelStatusBar;

或在任何其他类别中

[AppDelegate appDelegate].window.windowLevel = UIWindowLevelStatusBar;

如果你想让状态栏再次出现在顶部,你可以设置

self.window.windowLevel = UIWindowLevelNormal;

【讨论】:

【参考方案2】:

在 -[UIWindow makeKeyAndVisible] 的文档中:

这是一种使接收器成为主窗口并将其显示在其他窗口前面的便捷方法。您还可以使用 UIView 继承的 hidden 属性隐藏和显示窗口。

“关键窗口”是获取特定输入事件的窗口;非键窗口中的文本字段可能不起作用。您可以做两件事:

之后在键窗口上调用[window makeKeyAndVisible] 改为设置statusWindow.hidden = NO(但我不明白为什么它会默认隐藏)。我认为您不能像 -makeKeyAndVisible 那样“在其他窗口前显示它”; Windows 没有超级视图,您可以在 IIRC 上调用 -bringSubviewToFront:。

【讨论】:

你好,这太棒了!首先,我不相信它可以工作,但它确实做到了!非常感谢您节省了我的时间和挫败感! :-) 你最终使用了哪种方法? 查看我的上一篇文章:我不得不删除命令“statusWindow makeKeyAndVisible”并改用“statusWindow.hidden = NO”。在所有代码的末尾,我添加了“window makeKeyAndVisible”,因此应用程序知道它必须在那里显示键盘。有效!我希望苹果能接受这个解决方案。 它不使用任何“私有 API”,因此 Apple 不太可能拒绝它。可以在状态栏上方放置一个窗口,有点担心。 OTOH,没有什么能阻止你隐藏“真实”状态栏并显示一个克隆,所以这也不是一个很大的安全风险。【参考方案3】:

如果其他用户想实现这个,这里是我的解决方案:

// Create window
statusWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0,0,320,20)];
statusWindow.windowLevel = UIWindowLevelStatusBar;
// Dont make the statusWindow keyWindow or the keyboard won't work!
// [statusWindow makeKeyAndVisible];

// Create statusBarButton
statusBarButton = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect buttonFrame2 = statusBarButton.frame;
buttonFrame2.size = CGSizeMake(320,20);
statusBarButton.frame = buttonFrame2;
[statusBarButton addTarget:self action:@selector(goTop) forControlEvents:UIControlEventTouchUpInside]; 

// Place button into the new window
[statusWindow addSubview:statusBarButton];

// Instead, add this:
[window makeKeyAndVisible]; // has to be main window of app
statusWindow.hidden = NO; // without this the statusWindow won't appear

【讨论】:

此代码似乎不起作用。据我所知,您没有将statusWindow 添加到您的视图层次结构中。你如何让它出现? 我在我的 h 文件中声明了 window 和 statusWindow,并在我的 m 文件中进行了综合。据我检查,没有做任何其他事情!请注意,我的按钮是不可见的,并且仅位于状态栏的顶部,并且会调用需要声明的函数 goTop。 iPhone 应用旋转也会混淆这一点,因此您必须调整按钮的大小。 这对我也不起作用,这段代码在 AppDelegate 中?【参考方案4】:

试试:

[self.view bringSubviewToFront:statusWindow];

我不认为它可以在状态栏前面带来一个视图。

【讨论】:

不幸的是,我无法让它工作。唯一的方法是添加一个新的(通常不推荐!)。

以上是关于将 UIView 或 UIWindow 放在状态栏上方的主要内容,如果未能解决你的问题,请参考以下文章

在单独的 UIWindow 中锁定状态栏方向

添加新 UIWindow 时以编程方式隐藏状态栏?

状态栏与 UIWindow 分开旋转

iOS9:自定义 UIWindow 使状态栏消失

iOS开发-UI 补充 UIWindow UIView UIlabel

iOS9用自定义uiwindow覆盖状态栏 - 位置错误