3

After implementing a UIViewController, it seems that the status bar content colour doesn't change (still remains black) for some reason. How can it be changed to the 'light' mode (white colour) programatically only using Swift 4.0 for just this specific UIViewController? Not the whole application.

ViewController.swift class

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()            
        view.backgroundColor = UIColor.blue

        self.title = "Hello World"
        self.navigationController?.navigationBar.barTintColor = UIColor.gray
        self.navigationController?.navigationBar.prefersLargeTitles = true
        self.navigationController?.navigationItem.largeTitleDisplayMode = .automatic

        self.navigationController?.navigationBar.largeTitleTextAttributes = [
            NSAttributedStringKey.foregroundColor: UIColor.white,
            NSAttributedStringKey.font : UIFont.preferredFont(forTextStyle: .largeTitle)
        ]
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
}

enter image description here

jake.lange's suggestion

enter image description here

wbk727
  • 8,017
  • 12
  • 61
  • 125

3 Answers3

10

Your UINavigationController is the one setting the preferredStatusBarColor. I bet if you tried presenting this VC instead of pushing it to the navigation controller you'd see the light statusbar style.

What you'll probably want to do instead is implement a custom navigation controller and override preferred status bar style.

class CustomNavController: UINavigationController {
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent;
    }
}

EDIT:

Based on comments what you're probably looking to do is set the preferred status bar color to whatever ViewController is the top most of the UINavigationController. Here's an extension that does that, with this extension you no longer need the CustomNavController class above, just used a regular UINavigationController. You will also need to override the preferred status bar style in each of your view controllers. Credit to this SO question, see here for more in depth discussions on statusbarstyle and navigation controllers: preferredStatusBarStyle isn't called

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

    open override var childViewControllerForStatusBarHidden: UIViewController? {
        return self.topViewController
    }
}
Jacob Lange
  • 1,299
  • 14
  • 22
  • 1
    Not working for some reason. See latest screenshot above. – wbk727 Jun 02 '18 at 16:50
  • Your error is this line `window?.rootViewController = UINavigationController(rootViewController: CustomNavigationController())`. Change to `window?.rootViewController = CustomNavigationController(rootViewController: ViewController())` – Jacob Lange Jun 02 '18 at 17:19
  • This error then appears: `Use of unresolved identifier 'CustomNavigationController'` – wbk727 Jun 02 '18 at 17:29
  • Sorry, that's a spelling mistake on my part. fixed line would be `window?.rootViewController = CustomNavController(rootViewController: ViewController())` – Jacob Lange Jun 02 '18 at 17:32
  • What about if I want the default status bar colour (black) for a different `NavigationController`? How can I do that? – wbk727 Jun 03 '18 at 12:32
  • It depends on your application, I dont have the details necessary and I can only speculate what you want to do. I'll edit my answer with what I think you want to do. Remember that view controllers can be nested within each other (encouraged practice for separating concerns and reusing views), which is why the preferred statusbar color will be "ignored" sometimes as you posted in your original question, your ViewController is a child vc of the UINavigationController. – Jacob Lange Jun 03 '18 at 15:53
  • Just to clarify, I want some of my future view controllers to have `lightContent` in the status bar, and other future view controllers to have default status bar colour (black). I don't want either to be applied to ALL of them in my project. – wbk727 Jun 03 '18 at 16:12
  • That's fine, it's just that this all depends on your applications view controller hierarchy which will change as your application grows. If everything always lives within that original root UINavigationController then what I've edited into my answer should suffice. – Jacob Lange Jun 03 '18 at 16:34
  • Cool. Many thanks. Do you know how to solve this [other issue](https://stackoverflow.com/questions/50192321/how-to-add-vertical-bar-to-uitableviewcell-programmatically) by any chance? I've just come from an Android dev environment (which was much easier) - Swift is so annoying + interface builder is virtually pointless for a large project. – wbk727 Jun 03 '18 at 17:27
2

Can you check in the Info.plist file if this flag "View controller-based status bar appearance" is set to NO. It needs to be set YES in order to allow view controller based appearance.

0

Work's for me:

override func viewWillAppear(_ animated: Bool) {
  super.viewWillAppear(animated)

  self.navigationController?.navigationBar.barStyle = .blackTranslucent
  self.navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]
}

override var preferredStatusBarStyle: UIStatusBarStyle {
  return .lightContent
}