具有多个Windows的UIStatusBar外观

Aus*_*tin 5 uiviewcontroller uiwindow ios uistatusbar

首先,我的应用程序的设置:

大多数应用程序的视图控制器都存在于您的标准导航控制器层次结构中,但我还在主应用程序窗口上有第二个窗口,它主持一个视图控制器(NotificationVC).如果NotificationVC正在显示通知,它将更改状态栏样式以与通知形成对比,但否则它会将样式推迟到主窗口的根视图控制器.

我的问题是主窗口中的更改通常会触发状态栏外观更新(推送,弹出或呈现视图控制器或调用-[UIViewController setNeedsStatusBarAppearanceUpdate])无效.

以下是相关代码NotificationVC:

@implementation NotificationVC

- (UIStatusBarStyle)preferredStatusBarStyle
{
    if (self.isShowingNotification)
    {
        if (self.notificationView.hasDarkBackground)
        {
            return UIStatusBarStyleLightContent;
        }
        else
        {
            return UIStatusBarStyleDefault;
        }
    }
    else
    {
        return [[UIApplication sharedApplication].delegate window].rootViewController.preferredStatusBarStyle;
    }
}

@end
Run Code Online (Sandbox Code Playgroud)

如何让状态栏从主窗口中的一个视图控制器更新?

注意:手动设置状态栏外观(-[UIApplication setStatusBarStyle:])不适用于此应用程序.

Aus*_*tin 1

这似乎是 的一项优化UIViewController- 如果它不在顶部窗口中,则不会触发更新。

\n\n

我能够通过调整forUIViewController的实现来解决这个问题setNeedsStatusAppearanceUpdate,该实现知道通知视图控制器的窗口。

\n\n
@interface UIViewController (NotificationWindow)\n\n@end\n\n@implementation UIViewController (NotificationWindow)\n\n+ (void)load\n{\n    Method original = class_getInstanceMethod([UIViewController class], @selector(setNeedsStatusBarAppearanceUpdate));\n    Method swizzled = class_getInstanceMethod([UIViewController class], @selector(swiz_setNeedsStatusBarAppearanceUpdate));\n    method_exchangeImplementations(original, swizzled);\n}\n\n- (void)swiz_setNeedsStatusBarAppearanceUpdate\n{\n    UIWindow *topWindow = [UIApplication sharedApplication].windows.lastObject;\n\n    if (![self.view.window isEqual:topWindow] && [topWindow.rootViewController isKindOfClass:[NotificationVC class]])\n    {\n        [[[UIApplication sharedApplication].windows.lastObject rootViewController] swiz_setNeedsStatusBarAppearanceUpdate];\n    }\n    else\n    {\n        [self swiz_setNeedsStatusBarAppearanceUpdate];\n    }\n}\n\n@end\n
Run Code Online (Sandbox Code Playgroud)\n\n

这有点 hacky \xe2\x80\x94 我试图避免 swizzling \xe2\x80\x94 但它允许状态栏外观 API 按原样工作,而不需要每个其他视图控制器都知道NotificationVC.

\n