The correct way to set a light status bar text color in iOS 7 based on different ViewControllers

∥☆過路亽.° 提交于 2019-11-30 04:57:10

For people having this problem with a UINavigationController I can recommend creating a custom UINavigationController and implementing the preferredStatusBarStyle on it like this:

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return [self.topViewController preferredStatusBarStyle];
}

That way the statusbar style will be that of the top view controller. Now you can implement the view controller's preferredStatusBarStyle anyway you like.

Here's an improvement to Groot answer, in form of a simple category to UINavigationController, without the need to subclass UINavigationController.

Swift

extension UINavigationController {
    override public func preferredStatusBarStyle() -> UIStatusBarStyle {
        return topViewController?.preferredStatusBarStyle() ?? .Default
    }
}

Swift 3 & Swift 4

extension UINavigationController {
    open override var preferredStatusBarStyle: UIStatusBarStyle {
        return topViewController?.preferredStatusBarStyle ?? .default
    }
}

Objective-C

@implementation UINavigationController (StatusBarStyle)

- (UIStatusBarStyle)preferredStatusBarStyle 
{
    return [self.topViewController preferredStatusBarStyle];
}

@end

To set UIStatusBarStyle individually for each UIViewController on UINavigationController stack you have to first subclass your UINavigationController and override childViewControllerForStatusBarStyle method.

In your UINavigationController subclass add:

-(UIViewController *)childViewControllerForStatusBarStyle {
     return self.visibleViewController;
}

than you can set UIStatusBarStyle to whatever you want in every UIViewController using preferredStatusBarStyle method. Eg:

-(UIStatusBarStyle)preferredStatusBarStyle {
     return UIStatusBarStyleLightContent;
}

I used the first method you mentioned, I also found there's kinda bug when you used UINavigationController, it will never pass preferredStatusBarStyle call to it's child view controllers. What I have done is subclass the UINavigationController, and override preferredStatusBarStyle method as follows:

@implementation GLBaseNavigationController

- (UIStatusBarStyle)preferredStatusBarStyle
{
    UIViewController *lastViewController = [self.viewControllers lastObject];
    if ([lastViewController respondsToSelector:@selector(preferredStatusBarStyle)]) {
        return [lastViewController preferredStatusBarStyle];
    } else if ([super respondsToSelector:@selector(preferredStatusBarStyle)]) {
        return [super preferredStatusBarStyle];
    }
    return UIStatusBarStyleDefault;
}

Then whenever I need a navigation controller, I use GLBaseNavigationController instead of UINavigationController. For storyboards, you need to specify the class of the navigation controller to your subclass as well.

For your first solution, I don't think you can change the status bar in viewDidLoad. If you have two ViewControllers stacked on top of each other, and each one toggles the status bar differently, that method will only get called once for each. You really want to change the status bar in viewWillAppear so that it gets called each time the page is shown. I also don't think you can rely on preferredStatusBarStyle since I'm also not sure how often/when that gets called. This is how you want to do it:

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self.navigationController.navigationBar setBarStyle:UIBarStyleDefault];
}

Currently you can only do light and dark. To change to light do.

  1. Set the UIViewControllerBasedStatusBarAppearance to YES in the .plist file.

  2. In the viewDidLoad method do [self setNeedsStatusBarAppearanceUpdate];

  3. Add the this method:

-(UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; }

To change it back to dark change the UIStatusBarStyleLightContent to UIStatusBarStyleDefault

In your AppDelegate didFinishLaunch method, set the default status bar style, say:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault
                                                animated:YES];       
    return YES;
}

Then, in your those two view controllers, where you want to change status bar, override following methods:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated]        

    // Here change status bar color
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent
                                                animated:YES];       

}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear]                

    // Here bring back to color, that we set in AppDelegate
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault
                                                animated:YES];       
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!