16

I am trying to fill the status bar background color to orange using the following

UINavigationBar.appearance().tintColor = UIColor.orangeColor()
UINavigationBar.appearance().barTintColor = UIColor.orangeColor()
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()]
UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)

However, I get a white status bar that should be filled with orange instead from following this example: Customize navigation bar appearance with swift

I am setting this up in the AppDelegate.swift file under didFinishLaunchingWithOptions method to apply it to the entire app.

I have edited my info.plist to the following: View controller-based status bar appearance => NO

Does anyone know what I am doing wrong?

Edit: I'm not sure if it matters but the view is in a UITabBarController

Edit 2: This is happening in all the views actually, not just the UITabBarController.

Edit 3: Thanks @Utsav Parikh

I am adding a view now on top of the status bar and it for a brief moment while the app loads the status bar is orange but, once it finishes loading it gets pushed OFF the view and replaced with the generic white status bar. Why would this be happening?

let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.mainScreen().bounds.size.width, height: 20.0))
view.backgroundColor=UIColor.orangeColor()
self.window!.rootViewController!.view.addSubview(view) 

Edit for Swift 3:

with UITabBarController

let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width, height: 20.0))
view.backgroundColor = .orange
self.view.addSubview(view)

Without embedded controllers

I realize some people come here not only for the status bar, but actually the navigation bar, so I learned a few tricks along the way to do it without any embedded controllers:

Add this method in your AppDelegate.swift and call it in the didFinishLaunchingWithOptions

func customizeAppearance() {
    UINavigationBar.appearance().barTintColor = UIColor.black
    UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
    UITabBar.appearance().barTintColor = UIColor.black
    let tintColor = UIColor(red: 255/255.0, green: 255/255.0, blue: 255/255.0, alpha: 1.0)

    UITabBar.appearance().tintColor = tintColor
}
shim
  • 9,289
  • 12
  • 69
  • 108
Simon
  • 6,413
  • 6
  • 34
  • 57
  • Visit to this link... it may helps [here][1] [1]: http://stackoverflow.com/questions/26956728/changing-the-status-bar-color-for-specific-viewcontrollers-using-swift-in-ios8 – Ashok Londhe May 20 '15 at 05:51
  • @AshokLondhe I have used that link prior to asking this question with no luck as well. – Simon May 20 '15 at 06:08
  • Change the status bar style under General -> Target -> Status Bar Style. See if that has any effect. Also try changing the appearance after app delegate has started up via a dispatch after and wait 2 seconds – TheCodingArt May 20 '15 at 15:04
  • @TheCodingArt I have just tried that and it is the same effect. I am able to get the LightContent for status bar style, but am not getting the orange background that should populate on top of it – Simon May 21 '15 at 04:30
  • Just out of curiosity, I see that you aren't adding auto layout constraints. Could you please add constraints and ensure that you're view it added to the top of the top layout guide? That or bump your view's origin up to -20 on the Y axis. – TheCodingArt May 21 '15 at 13:41
  • I have added constraints from the navigation bar to the top layout guide and the results are still the same. – Simon May 21 '15 at 21:43

9 Answers9

26

Edit for Swift 3:

With UITabBarController

let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width, height: 20.0))
view.backgroundColor = .orange
self.view.addSubview(view)

Without embedded controllers

I realize some people come here not only for the status bar, but actually the navigation bar, so I learned a few tricks along the way to do it without any embedded controllers:

Add this method in your AppDelegate.swift and call it in the didFinishLaunchingWithOptions

func customizeAppearance() {
    UINavigationBar.appearance().barTintColor = UIColor.black
    UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
    UITabBar.appearance().barTintColor = UIColor.black
    let tintColor = UIColor(red: 255/255.0, green: 255/255.0, blue: 255/255.0, alpha: 1.0)

    UITabBar.appearance().tintColor = tintColor
}

Thanks to @Utsav I added the following subview to my UITabBarController and this seems to be working now:

    let view = UIView(frame:
                    CGRect(x: 0.0, y: 0.0, width: UIScreen.mainScreen().bounds.size.width, height: 20.0)
                )
    view.backgroundColor = UIColor.orangeColor()

    self.view.addSubview(view)

The UITabBarController doesn't seem to play well in AppDelegate. If anyone has a better way let me know but, as of now this is the solution I have come around to.

TheCrazyProfessor
  • 919
  • 1
  • 15
  • 31
Simon
  • 6,413
  • 6
  • 34
  • 57
  • If I add this code like directed, I get the error `Cannot call value of non-function type 'UIScreen'`, I'm using swift 3 and xcode 8. Any suggestions? I've started a bounty on this question, so if you can figure this one out you get 50 Rep. – Emmet Arries Dec 26 '16 at 05:23
  • @EmmetArries I have updated the original post without UITabBarController – Simon Dec 28 '16 at 18:11
  • Ok. I'm pretty new to Xcode and even less experienced with Swift. I tried the code of your second option where you specified and nothing changed. Here's what I need: I have a single view app that only has a UIWebView that takes up the whole screen. I just need something that can change the background and text color of the status bar. (Ideally the text would be white and the background 0.5% opacity, or transparency) Is that possible? If you need more details, let me know! – Emmet Arries Dec 29 '16 at 23:53
  • 1
    @EmmetArries try adding `UIApplication.shared.statusBarStyle = .lightContent` to the `customizeAppearance()` method. without knowing anymore context it seems your whole UIWebView covers the whole screen which would make it not possible to change the status bar background. you would need to move the web view down 20pt since that's the height of the status bar – Simon Dec 30 '16 at 00:32
  • @Simon AHA! You where onto something! Your code didn't work out, but I got the background color I wanted. Thank you! – Emmet Arries Dec 30 '16 at 00:50
16

Add this code in didFinishLaunchingWithOptions in AppDelegate

let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.mainScreen().bounds.size.width, height: 20.0))
view.backgroundColor=UIColor.orangeColor()
self.window.rootViewController.view.addSubview(view)

Hope it helps you....!!!

Utsav Parikh
  • 1,216
  • 7
  • 14
  • 1
    "UIScreen does not have a member named bounds" is the error that I'm currently getting when I try this answer @Utsav – Simon May 21 '15 at 04:21
  • @Simon try UIScreen.mainScreen().bounds.size.width instead of UIScreen.mainScreen.bounds.size.width – Utsav Parikh May 21 '15 at 04:32
  • 1
    I have just tried this and for a brief moment it adds the orange status bar while it is loading but, once it finishes loading it gets pushed OUT of the view and replaced with a white one? – Simon May 21 '15 at 04:43
6

This is how I did it without adding a view in a VC with in a NavBarController

I wanted the color of the status bar to be the same as the VC view color so I just wrote:

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.backgroundColor = UIColor.grayColor()
    self.navigationController?.navigationBar.clipsToBounds = true
}

Try it.

naz
  • 1,478
  • 2
  • 21
  • 32
1

I think your last line is reverting your changes, try this:

override func viewWillAppear(animated: Bool) {
UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)
        super.viewWillAppear(animated)
        var nav = self.navigationController?.navigationBar
        nav?.barStyle = UIBarStyle.Black
        nav?.tintColor = UIColor.orangeColor()
        nav?.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()]
    }
Icaro
  • 14,585
  • 6
  • 60
  • 75
1

After what u did in info.plist to the following: View controller-based status bar appearance => NO.

Add this code in AppDelegate.swift file under didFinishLaunchingWithOptions:

var navigationBarAppearace = UINavigationBar.appearance()

navigationBarAppearace.tintColor = uicolorFromHex(0xffffff)
navigationBarAppearace.barTintColor = uicolorFromHex(0x2E9AFE)

// change navigation item title color
navigationBarAppearace.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.whiteColor()]

UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent

and u can select any hex code for ur choice of color..!! Enjoy..!!

Sorry, forgot to use hexcode you will be needing this also so add this code anywhere in your AppDelegate.swift:

func uicolorFromHex(rgbValue:UInt32)->UIColor {

    let red = CGFloat((rgbValue & 0xFF0000) >> 16)/256.0

    let green = CGFloat((rgbValue & 0xFF00) >> 8)/256.0

    let blue = CGFloat(rgbValue & 0xFF)/256.0

    return UIColor(red:red, green:green, blue:blue, alpha:1.0)
}
Maury Markowitz
  • 9,082
  • 11
  • 46
  • 98
Irshad Qureshi
  • 807
  • 18
  • 41
1

Simon's answer in swift 3

let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width, height: 20.0))
view.backgroundColor = .orange
self.view.addSubview(view)

There is one other way I know which uses private api. This has some benefits when orientation changes and keyboard is presented and view move up. I've used it and was lucky every time (app was released in the app store).

func setStatusBarBackgroundColor(color: UIColor) {

    guard let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView else { return }

    statusBar.backgroundColor = color
} 
Warif Akhand Rishi
  • 23,920
  • 8
  • 80
  • 107
  • What do you mean by "private api"? How would I set the color on the second option? And what do you mean by "lucky"? Does the app store not usually accept that way of doing things? Sorry I have so many questions, but I'm new to swift. – Emmet Arries Dec 26 '16 at 19:54
  • BTW I don't have a UITabBarController, so the first answer doesn't work for me. – Emmet Arries Dec 26 '16 at 20:13
1

Swift 3:

In your AppDelegate.swift file paste the code bellow into your didFinishLaunchingWithOptions method:

let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: UIScreen.main.bounds.size.width, height: 20.0))
view.backgroundColor = UIColor(red: 255/255, green: 130/255, blue: 0/255, alpha: 1.0) // Organge colour in RGB
self.window?.rootViewController?.view.addSubview(view)

This works fine for me!

Bruno Campos
  • 405
  • 7
  • 6
  • Statusbar height should be dynamic, and colour needs to take `UIUserInterfaceStyle` into consideration. – Johan Feb 28 '20 at 15:33
0

There is a main difference in tintColor and changing the background color of UINavigationBar. The best way in my opinion is apply a background image, made by 1 pixel square image of just one color.
Like that:

let tabbarAndNavBarBkg = UIImage(named: "nav_tab")
UINavigationBar.appearance().setBackgroundImage(tabbarAndNavBarBkg, forBarMetrics: .Default) 

Or you can create a category on UIColor to return a UIImage given a UIColor instance, in objC:

+ (UIImage *) imageWithColor:(UIColor*) color {
    CGRect rect = CGRectMake(0, 0, 1, 1);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, rect);
    UIImage *colorImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return colorImage;
}
Andrea
  • 26,120
  • 10
  • 85
  • 131
  • I have tried this to no success. Should I apply a view on top instead? How would I go about doing that? – Simon May 21 '15 at 04:35
  • If you create an image with a solid color as written in the first line, does it work? – Andrea May 21 '15 at 04:48
  • I created the image with a solid colour, it did not work. I edited my original post. I added a view and it seems that it is getting pushed up by the UITabBarController after it finishes loading? – Simon May 21 '15 at 04:55
  • You don't need to do nothing else than calling what I posted inside applicationDidFinishLaunching. If it doesn't work probably you are doing something wrong or the information given are not totally correct about the state of your project. Are you sure that the image is created after calling the image from colo method? – Andrea May 21 '15 at 06:10
  • Yes, the image is being called but it applies only in the navigation bar area. The status bar is still left white. I would post an image if I could right now. – Simon May 21 '15 at 11:50
0

UINavigationBar.appereance() works for upcoming viewControllers, but not the currently displayed rootViewController. To achieve this I have added the following to my didFinishLaunchingWithOptions:

UINavigationBar.appearance().tintColor = myColor

let navigationController = UIApplication.sharedApplication().windows[0].rootViewController as! UINavigationController
navigationController.navigationBar.barTintColor = myColor
navigationController.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName : myTextColor]
navigationController.navigationBar.translucent = false

navigationController.setNeedsStatusBarAppearanceUpdate()
zisoft
  • 22,770
  • 10
  • 62
  • 73
  • Unfortunately, this does not solve my problem either. It is actually be segued to this view (UITabBarController) through an initial UIView. – Simon May 21 '15 at 04:38