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

8
当我在iOS9中创建一个自定义UIWindow时,窗口会在屏幕上可见,但状态栏会突然消失。当窗口被隐藏时,状态栏会再次出现。以下是使用Xcode7 beta5在iOS9上获得的2个屏幕截图。在自定义窗口隐藏时的状态栏:Status bar while the custom window is hidden。在自定义窗口可见时的状态栏:Status bar while the custom window is visible(整个屏幕向上移动)。这是我正在使用的代码(在iOS8上运行良好):
#define DEBUG_SHOWENV_HEIGHT 20.0f

@interface AppDelegate ()
@property (nonatomic) UIWindow*     envWindow;
@end

-(UIWindow*)envWindow
{
    if (_envWindow == nil)
    {
        // Create the window
        _envWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0.0f, self.window.frame.size.height, self.window.frame.size.width, DEBUG_SHOWENV_HEIGHT)];
        _envWindow.rootViewController = [[UIViewController alloc] init]; // added since iOS9 to avoid the assertion
        _envWindow.userInteractionEnabled = NO;
        _envWindow.windowLevel = UIWindowLevelStatusBar;
        _envWindow.backgroundColor = [UIColor colorWithRed:0.243 green:0.471 blue:0.992 alpha:0.8];

        // Make a label
        UILabel* labelEnv = [[UILabel alloc] initWithFrame:CGRectMake(8.0f, 0.0f, _envWindow.bounds.size.width - 16.0f, DEBUG_SHOWENV_HEIGHT)];
        labelEnv.font = [UIFont boldSystemFontOfSize:12.0f];
        labelEnv.textColor = [UIColor whiteColor];
        labelEnv.text = @"DEVELOP ENVIRONMENT";
        [_envWindow addSubview:labelEnv];
    }
    return _envWindow;
}

// ==== in applicationDidBecomeActive

// Show the window 2 seconds then hide it.
[self.envWindow.layer removeAllAnimations];
self.envWindow.frame = CGRectMake(0.0f, self.window.frame.size.height, self.window.frame.size.width, DEBUG_SHOWENV_HEIGHT);
self.envWindow.hidden = NO;
[UIView animateWithDuration:0.25f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^{
                     self.envWindow.frame = CGRectMake(0.0f, self.window.frame.size.height - DEBUG_SHOWENV_HEIGHT, self.window.frame.size.width, DEBUG_SHOWENV_HEIGHT);
                 }
                 completion:^(BOOL finished) {

                     if (finished)
                     {
                         [UIView animateWithDuration:0.25f
                                               delay:2.0f
                                             options:UIViewAnimationOptionCurveEaseOut
                                          animations:^{
                                              self.envWindow.frame = CGRectMake(0.0f, self.window.frame.size.height, self.window.frame.size.width, DEBUG_SHOWENV_HEIGHT);
                                          }
                                          completion:^(BOOL finished) {

                                              if (finished)
                                              {
                                                  self.envWindow.hidden = YES;
                                              }
                                          }];
                     }
                 }];

我会非常感激您的帮助。


为什么你有一个自定义窗口,而不是只有一个 UIViewController - NRitH
因为我希望它在应用程序每次变为活动状态时都能显示(即使在过渡期间等)。 - Runo Sahara
2个回答

6

问题已解决。 我需要在根视图控制器中实现此方法:

- (BOOL)prefersStatusBarHidden
{
    return NO;
}

由于某些原因,此UIWindow中的根视图控制器隐藏了状态栏。(虽然默认情况下应该返回NO)
所以,不要这样做:
_envWindow.rootViewController = [[UIViewController alloc] init]; // added since iOS9 to avoid the assertion

我创建了自己的视图控制器,并覆盖了prefersStatusBarHidden方法。


1
这行代码 _envWindow.windowLevel = UIWindowLevelStatusBar; 将你的窗口放置在与状态栏相同的层级(z-ordering)。我认为你想要的是 UIWindowLevelNormal,这样状态栏就会出现在它上面。

没有解决我的问题。似乎不仅是绘制顺序的问题,当状态栏不存在时,视图内容会移动到屏幕顶部。 - Runo Sahara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接