UIStatusBarStyle PreferredStatusBarStyle does not

2019-01-08 04:50发布

In my iPhone application built with Xcode 5 for iOS 7 I set UIViewControllerBasedStatusBarAppearance=YES in info.plist, and in my ViewController I have this code:

-(UIStatusBarStyle) preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

But the status bar is still black against the black background.

I know its possible to change this app-wide by setting UIViewControllerBasedStatusBarAppearance=NO in info.plist, but I actually need to alter this on a viewController by viewController basis at runtime.

16条回答
对你真心纯属浪费
2楼-- · 2019-01-08 05:11

swift example

in AppDelegate.swift

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
    UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent;

    return true
}

in info.plist set View controller-based status bar appearance: NO

查看更多
Fickle 薄情
3楼-- · 2019-01-08 05:11

If you're using NavigationController, you can subclass NavigationController so that it consults its child view controller

// MyCustomNavigationController

- (NSUInteger)supportedInterfaceOrientations {
    UIViewController *viewControllerToAsk = [self findChildVC];
    return [viewControllerToAsk supportedInterfaceOrientations];
}

- (BOOL)shouldAutorotate {
    UIViewController *viewControllerToAsk = [self findChildVC];
    return [viewControllerToAsk shouldAutorotate];
}

- (UIStatusBarStyle)preferredStatusBarStyle {
    UIViewController *viewControllerToAsk = [self findChildVC];
    return [viewControllerToAsk preferredStatusBarStyle];
}

- (UIViewController *)findChildVC {
    return self.viewControllers.firstObject;
}
查看更多
Deceive 欺骗
4楼-- · 2019-01-08 05:11

I just want to add a note for a specific case I faced. I had another UIWindow in my app to display a chat face to be floating all over my app all the time. Doing this caused none of the solution above to work, and I am not really sure why! All what I have noticed is that my ViewController in the new UIWindow was the reason for that! And if I wanted to change the status bar style I have to do it in that view controller of the new UIWindow.

This note might help others who have a similar structure! So basically you can apply the solutions mentioned above in the ViewController of the new UIWindow.

Again this a specific case.

Thanks

查看更多
劫难
5楼-- · 2019-01-08 05:12

For preferredStatusBarStyle() to work within UINavigationController and UITabBarController I add the following code, which will get the preferred status bar style from the currently visible view controller.

extension UITabBarController {
    public override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
    public override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return visibleViewController
    }
}

For Swift 3 those are not methods but properties:

extension UITabBarController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return visibleViewController
    }
}

The Swift 4.2 properties have been renamed:

extension UITabBarController {
   open override var childForStatusBarStyle: UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
   open override var childForStatusBarStyle: UIViewController? {
        return visibleViewController
    }
}

Usage

class ViewController: UIViewController {

    // This will be called every time the ViewController appears
    // Works great for pushing & popping
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }

}
查看更多
做个烂人
6楼-- · 2019-01-08 05:12

In viewDidLoad just write this

[self setNeedsStatusBarAppearanceUpdate];

just do that and it will work

can u please try this

Set UIViewControllerBasedStatusBarAppearance to NO.
Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

One more thing i have seen in your question that you have wrote the method like this

 -(void)UIStatusBarStyle PreferredStatusBarStyle ()
        {
            return UIStatusBarStyle.LightContent;
        }

but it should be like this

-(UIStatusBarStyle)preferredStatusBarStyle{ 
    return UIStatusBarStyleLightContent; 
} 
查看更多
趁早两清
7楼-- · 2019-01-08 05:14

Even with all the answers here i still didn't find the exact solution for me, but started with the answer from Daniel. What I ended up with was:

override var preferredStatusBarStyle: UIStatusBarStyle {
     return visibleViewController?.preferredStatusBarStyle ?? .lightContent
}

in navigation controllers (similar for tab, just selectedViewController). And then it will respect the:

override var preferredStatusBarStyle: UIStatusBarStyle {
     return .lightContent
}

In each view controller unless you set it otherwise. I dont need to call setNeedsStatusBarAppearanceUpdate() anywhere, it just updates when you arrive at each view controller.

查看更多
登录 后发表回答