preferredStatusBarStyle isn't called

2019-01-01 16:35发布

I followed this thread to override -preferredStatusBarStyle, but it isn't called. Are there any options that I can change to enable it? (I'm using XIBs in my project.)

20条回答
永恒的永恒
2楼-- · 2019-01-01 17:05

My app used all three: UINavigationController, UISplitViewController, UITabBarController, thus these all seem to take control over the status bar and will cause preferedStatusBarStyle to not be called for their children. To override this behavior you can create an extension like the rest of the answers have mentioned. Here is an extension for all three, in Swift 4. Wish Apple was more clear about this sort of stuff.

extension UINavigationController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return self.topViewController
    }

    open override var childViewControllerForStatusBarHidden: UIViewController? {
        return self.topViewController
    }
}

extension UITabBarController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return self.childViewControllers.first
    }

    open override var childViewControllerForStatusBarHidden: UIViewController? {
        return self.childViewControllers.first
    }
}

extension UISplitViewController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return self.childViewControllers.first
    }

    open override var childViewControllerForStatusBarHidden: UIViewController? {
        return self.childViewControllers.first
    }
}
查看更多
与君花间醉酒
3楼-- · 2019-01-01 17:06

Tyson's answer is correct for changing the status bar color to white in UINavigationController.

If anyone want's to accomplish the same result by writing the code in AppDelegate then use below code and write it inside AppDelegate's didFinishLaunchingWithOptions method.

And don't forget to set the UIViewControllerBasedStatusBarAppearance to YES in the .plist file, else the change will not reflect.

Code

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     // status bar appearance code
     [[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];

     return YES;
}
查看更多
若你有天会懂
4楼-- · 2019-01-01 17:07

@serenn's answer above is still a great one for the case of UINavigationControllers. However, for swift 3 the childViewController functions have been changed to vars. So the UINavigationController extension code should be:

override open var childViewControllerForStatusBarStyle: UIViewController? {
  return topViewController
}

override open var childViewControllerForStatusBarHidden: UIViewController? {
  return topViewController
}

And then in the view controller that should dictate the status bar style:

override var preferredStatusBarStyle: UIStatusBarStyle {
   return .lightContent
}
查看更多
孤独寂梦人
5楼-- · 2019-01-01 17:08

In addition to serenn's answer, if you are presenting a view controller with a modalPresentationStyle (for example .overCurrentContext), you should also call this on the newly presented view controller:

presentedViewController.modalPresentationCapturesStatusBarAppearance = true

Don't forget to also override the preferredStatusBarStyle in the presented view controller.

查看更多
呛了眼睛熬了心
6楼-- · 2019-01-01 17:12

An addition to Hippo's answer: if you're using a UINavigationController, then it's probably better to add a category:

//  UINavigationController+StatusBarStyle.h:

@interface UINavigationController (StatusBarStyle)

@end



//  UINavigationController+StatusBarStyle.m:

@implementation UINavigationController (StatusBarStyle)

- (UIStatusBarStyle)preferredStatusBarStyle
{
    //also you may add any fancy condition-based code here
    return UIStatusBarStyleLightContent;
}

@end

That solution is probably better than switching to soon-to-be deprecated behaviour.

查看更多
余生请多指教
7楼-- · 2019-01-01 17:12

Most of the answers don't include good implementation of childViewControllerForStatusBarStyle method for UINavigationController. According to my experience you should handle such cases as when transparent view controller is presented over navigation controller. In these cases you should pass control to your modal controller (visibleViewController), but not when it's disappearing.

override var childViewControllerForStatusBarStyle: UIViewController? {
  var childViewController = visibleViewController
  if let controller = childViewController, controller.isBeingDismissed {
    childViewController = topViewController
  }
  return childViewController?.childViewControllerForStatusBarStyle ?? childViewController
}
查看更多
登录 后发表回答