如何改变状态栏背景颜色和文本颜色在 iOS7?

我当前的应用程序运行在 iOS5和6上。

导航栏的颜色是橙色,状态栏的背景颜色是黑色,文本颜色是白色。但是,当我在 iOS7上运行同样的应用程序时,我发现状态栏看起来是透明的,与导航栏的背景颜色一样是橙色,而状态栏的文本颜色是黑色。

由于这个原因,我无法区分状态栏和导航栏。

如何使状态栏看起来与 iOS5和 iOS6一样,即黑色背景色和白色文本色?我如何以编程方式做到这一点?

243659 次浏览

In iOS 7 the status bar doesn't have a background, therefore if you put a black 20px-high view behind it you will achieve the same result as iOS 6.

Also you may want to read the iOS 7 UI Transition Guide for further information on the subject.

1) set the UIViewControllerBasedStatusBarAppearance to YES in the plist

2) in viewDidLoad do a [self setNeedsStatusBarAppearanceUpdate];

3) add the following method:

 -(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}

UPDATE:
also check developers-guide-to-the-ios-7-status-bar

For bar color: You provide a custom background image for the bar.

For text color: Use the information in About Text Handling in iOS

Write this in your ViewDidLoad Method:

if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {
self.edgesForExtendedLayout=UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars=NO;
self.automaticallyAdjustsScrollViewInsets=NO;
}

It fixed status bar color for me and other UI misplacements also to a extent.

for the background you can easily add a view, like in example:

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0,320, 20)];
view.backgroundColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.1];
[navbar addSubview:view];

where "navbar" is a UINavigationBar.

Goto your app info.plist

1) Set View controller-based status bar appearance to NO
2) Set Status bar style to UIStatusBarStyleLightContent

Then Goto your app delegate and paste the following code where you set your Windows's RootViewController.

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)


if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0"))
{
UIView *view=[[UIView alloc] initWithFrame:CGRectMake(0, 0,[UIScreen mainScreen].bounds.size.width, 20)];
view.backgroundColor=[UIColor blackColor];
[self.window.rootViewController.view addSubview:view];
}

Hope it helps.

Just to add to Shahid's answer - you can account for orientation changes or different devices using this (iOS7+):

- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...


//Create the background
UIView* statusBg = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.window.frame.size.width, 20)];
statusBg.backgroundColor = [UIColor colorWithWhite:1 alpha:.7];


//Add the view behind the status bar
[self.window.rootViewController.view addSubview:statusBg];


//set the constraints to auto-resize
statusBg.translatesAutoresizingMaskIntoConstraints = NO;
[statusBg.superview addConstraint:[NSLayoutConstraint constraintWithItem:statusBg attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:statusBg.superview attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]];
[statusBg.superview addConstraint:[NSLayoutConstraint constraintWithItem:statusBg attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:statusBg.superview attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0]];
[statusBg.superview addConstraint:[NSLayoutConstraint constraintWithItem:statusBg attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:statusBg.superview attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]];
[statusBg.superview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[statusBg(==20)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(statusBg)]];
[statusBg.superview setNeedsUpdateConstraints];
...
}

While handling the background color of status bar in iOS 7, there are 2 cases

Case 1: View with Navigation Bar

In this case use the following code in your viewDidLoad method

 UIApplication *app = [UIApplication sharedApplication];
CGFloat statusBarHeight = app.statusBarFrame.size.height;


UIView *statusBarView = [[UIView alloc] initWithFrame:CGRectMake(0, -statusBarHeight, [UIScreen mainScreen].bounds.size.width, statusBarHeight)];
statusBarView.backgroundColor = [UIColor yellowColor];
[self.navigationController.navigationBar addSubview:statusBarView];

Case 2: View without Navigation Bar

In this case use the following code in your viewDidLoad method

 UIApplication *app = [UIApplication sharedApplication];
CGFloat statusBarHeight = app.statusBarFrame.size.height;


UIView *statusBarView =  [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, statusBarHeight)];
statusBarView.backgroundColor  =  [UIColor yellowColor];
[self.view addSubview:statusBarView];

Source link http://code-ios.blogspot.in/2014/08/how-to-change-background-color-of.html

Change background color of status bar: Swift:

let proxyViewForStatusBar : UIView = UIView(frame: CGRectMake(0, 0,self.view.frame.size.width, 20))
proxyViewForStatusBar.backgroundColor=UIColor.whiteColor()
self.view.addSubview(proxyViewForStatusBar)

In the case of swift 2.0 on iOS 9

Place the following in the app delegate, under didFinishLaunchingWithOptions:

    let view: UIView = UIView.init(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.size.width, 20))


view.backgroundColor = UIColor.blackColor()  //The colour you want to set


view.alpha = 0.1   //This and the line above is set like this just if you want
the status bar a darker shade of
the colour you already have behind it.


self.window!.rootViewController!.view.addSubview(view)

iTroid23 solution worked for me. I missed the Swift solution. So maybe this is helpful:

1) In my plist I had to add this:

<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>

2) I didn't need to call "setNeedsStatusBarAppearanceUpdate".

3) In swift I had to add this to my UIViewController:

override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}

Warning: It does not work anymore with iOS 13 and Xcode 11.

========================================================================

I had to try look for other ways. Which does not involve addSubview on window. Because I am moving up the window when keyboard is presented.

Objective-C

- (void)setStatusBarBackgroundColor:(UIColor *)color {


UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];


if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
statusBar.backgroundColor = color;
}
}

Swift

func setStatusBarBackgroundColor(color: UIColor) {


guard  let statusBar = UIApplication.sharedApplication().valueForKey("statusBarWindow")?.valueForKey("statusBar") as? UIView else {
return
}


statusBar.backgroundColor = color
}

Swift 3

func setStatusBarBackgroundColor(color: UIColor) {


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


statusBar.backgroundColor = color
}

Calling this form application:didFinishLaunchingWithOptions worked for me.

N.B. We have an app in the app store with this logic. So I guess it is okay with the app store policy.


Edit:

Use at your own risk. Form the commenter @Sebyddd

I had one app rejected cause of this, while another was accepted just fine. They do consider it private API usage, so you are subject to luck during the reviewing process :) – Sebyddd

Here's a total, copy and paste solution, with an

absolutely correct explanation

of every issue involved.

With thanks to Warif Akhand Rishi !

for the amazing find regarding keyPath statusBarWindow.statusBar. Good one.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    

// handle the iOS bar!
    

// >>>>>NOTE<<<<<
// >>>>>NOTE<<<<<
// >>>>>NOTE<<<<<
// "Status Bar Style" refers to the >>>>>color of the TEXT<<<<<< of the Apple status bar,
// it does NOT refer to the background color of the bar. This causes a lot of confusion.
// >>>>>NOTE<<<<<
// >>>>>NOTE<<<<<
// >>>>>NOTE<<<<<
    

// our app is white, so we want the Apple bar to be white (with, obviously, black writing)
    

// make the ultimate window of OUR app actually start only BELOW Apple's bar....
// so, in storyboard, never think about the issue. design to the full height in storyboard.
let h = UIApplication.shared.statusBarFrame.size.height
let f = self.window?.frame
self.window?.frame = CGRect(x: 0, y: h, width: f!.size.width, height: f!.size.height - h)
    

// next, in your plist be sure to have this: you almost always want this anyway:
// <key>UIViewControllerBasedStatusBarAppearance</key>
// <false/>
    

// next - very simply in the app Target, select "Status Bar Style" to Default.
// Do nothing in the plist regarding "Status Bar Style" - in modern Xcode, setting
// the "Status Bar Style" toggle simply sets the plist for you.
    

// finally, method A:
// set the bg of the Apple bar to white.  Technique courtesy Warif Akhand Rishi.
// note: self.window?.clipsToBounds = true-or-false, makes no difference in method A.
if let sb = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView {
sb.backgroundColor = UIColor.white
// if you prefer a light gray under there...
//sb.backgroundColor = UIColor(hue: 0, saturation: 0, brightness: 0.9, alpha: 1)
}
    

/*
// if you prefer or if necessary, method B:
// explicitly actually add a background, in our app, to sit behind the apple bar....
self.window?.clipsToBounds = false // MUST be false if you use this approach
let whiteness = UIView()
whiteness.frame = CGRect(x: 0, y: -h, width: f!.size.width, height: h)
whiteness.backgroundColor = UIColor.green
self.window!.addSubview(whiteness)
*/
    

return true
}

If you're using a UINavigationController, you can use an extension like this:

extension UINavigationController {
private struct AssociatedKeys {
static var navigationBarBackgroundViewName = "NavigationBarBackground"
}


var navigationBarBackgroundView: UIView? {
get {
return objc_getAssociatedObject(self,
&AssociatedKeys.navigationBarBackgroundViewName) as? UIView
}
set(newValue) {
objc_setAssociatedObject(self,
&AssociatedKeys.navigationBarBackgroundViewName,
newValue,
.OBJC_ASSOCIATION_RETAIN)
}
}


func setNavigationBar(hidden isHidden: Bool, animated: Bool = false) {
if animated {
UIView.animate(withDuration: 0.3) {
self.navigationBarBackgroundView?.isHidden = isHidden
}
} else {
navigationBarBackgroundView?.isHidden = isHidden
}
}


func setNavigationBarBackground(color: UIColor, includingStatusBar: Bool = true, animated: Bool = false) {
navigationBarBackgroundView?.backgroundColor = UIColor.clear
navigationBar.backgroundColor = UIColor.clear
navigationBar.barTintColor = UIColor.clear


let setupOperation = {
if includingStatusBar {
self.navigationBarBackgroundView?.isHidden = false
if self.navigationBarBackgroundView == nil {
self.setupBackgroundView()
}
self.navigationBarBackgroundView?.backgroundColor = color
} else {
self.navigationBarBackgroundView?.isHidden = true
self.navigationBar.backgroundColor = color
}
}


if animated {
UIView.animate(withDuration: 0.3) {
setupOperation()
}
} else {
setupOperation()
}
}


private func setupBackgroundView() {
var frame = navigationBar.frame
frame.origin.y = 0
frame.size.height = 64


navigationBarBackgroundView = UIView(frame: frame)
navigationBarBackgroundView?.translatesAutoresizingMaskIntoConstraints = true
navigationBarBackgroundView?.autoresizingMask = [.flexibleWidth, .flexibleBottomMargin]


navigationBarBackgroundView?.isUserInteractionEnabled = false


view.insertSubview(navigationBarBackgroundView!, aboveSubview: navigationBar)
}
}

It basically makes the navigation bar background transparent and uses another UIView as the background. You can call the setNavigationBarBackground method of your navigation controller to set the navigation bar background color together with the status bar.

Keep in mind that you have to then use the setNavigationBar(hidden: Bool, animated: Bool) method in the extension when you want to hide the navigation bar otherwise the view that was used as the background will still be visible.

You can set background color for status bar during application launch or during viewDidLoad of your view controller.

extension UIApplication {


var statusBarView: UIView? {
return value(forKey: "statusBar") as? UIView
}


}


// Set upon application launch, if you've application based status bar
class AppDelegate: UIResponder, UIApplicationDelegate {


var window: UIWindow?


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UIApplication.shared.statusBarView?.backgroundColor = UIColor.red
return true
}
}




or
// Set it from your view controller if you've view controller based statusbar
class ViewController: UIViewController {


override func viewDidLoad() {
super.viewDidLoad()


UIApplication.shared.statusBarView?.backgroundColor = UIColor.red
}


}



Here is result:

enter image description here


Here is Apple Guidelines/Instruction about status bar change. Only Dark & light (while & black) are allowed in status bar.

Here is - How to change status bar style:

If you want to set status bar style, application level then set UIViewControllerBasedStatusBarAppearance to NO in your `.plist' file.

if you wan to set status bar style, at view controller level then follow these steps:

  1. Set the UIViewControllerBasedStatusBarAppearance to YES in the .plist file, if you need to set status bar style at UIViewController level only.
  2. In the viewDidLoad add function - setNeedsStatusBarAppearanceUpdate

  3. override preferredStatusBarStyle in your view controller.

-

override func viewDidLoad() {
super.viewDidLoad()
self.setNeedsStatusBarAppearanceUpdate()
}


override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}

Try this. Use this code in your appdelegate class didFinishLaunchingWithOptions function:

[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
[application setStatusBarHidden:NO];
UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
statusBar.backgroundColor = [UIColor blackColor];
}

I succeeded to customize StatusBar color pretty simple adding in AppDelegate.cs file in the method:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)

next code:

UIView statusBar = UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) as UIView;


if (statusBar!=null && statusBar.RespondsToSelector(new Selector("setBackgroundColor:")))
{
statusBar.BackgroundColor = Color.FromHex(RedColorHex).ToUIColor();
}

So you get something like this:

enter image description here

Link: https://jorgearamirez.wordpress.com/2016/07/18/lesson-x-effects-for-the-status-bar/

Swift 4

In Info.plist add this property

View controller-based status bar appearance to NO

and after that in AppDelegate inside the didFinishLaunchingWithOptions add these lines of code

UIApplication.shared.isStatusBarHidden = false
UIApplication.shared.statusBarStyle = .lightContent

Swift 4:

// Change status bar background color

let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView


statusBar?.backgroundColor = UIColor.red

In Swift 5 and Xcode 10.2

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.1 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: {


//Set status bar background colour
let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView
statusBar?.backgroundColor = UIColor.red
//Set navigation bar subView background colour
for view in controller.navigationController?.navigationBar.subviews ?? [] {
view.tintColor = UIColor.white
view.backgroundColor = UIColor.red
}
})

Here i fixed status bar background colour and navigation bar background colour. If you don't want navigation bar colour comment it.

Swift code

let statusBarView = UIView(frame: CGRect(x: 0, y: 0, width: view.width, height: 20.0))
statusBarView.backgroundColor = UIColor.red
self.navigationController?.view.addSubview(statusBarView)

The below code snippet should work with Objective C.

if (@available(iOS 13.0, *)) {
UIView *statusBar = [[UIView alloc]initWithFrame:[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager.statusBarFrame] ;
statusBar.backgroundColor = [UIColor whiteColor];
[[UIApplication sharedApplication].keyWindow addSubview:statusBar];
} else {
// Fallback on earlier versions
UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
statusBar.backgroundColor = [UIColor whiteColor];//set whatever color you like
}
}

You can use like below, for iOS 13* and Swift 4.

1 -> Set View controller-based status bar appearance to NO

extension UIApplication {
var statusBarView: UIView? {
if #available(iOS 13.0, *) {
let statusBar =  UIView()


statusBar.frame = UIApplication.shared.statusBarFrame


UIApplication.shared.keyWindow?.addSubview(statusBar)
      

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

in didFinishLaunchingWithOptions

UIApplication.shared.statusBarView?.backgroundColor = UIColor.red

Use This Extention

extension UINavigationController {


func setStatusBar(backgroundColor: UIColor) {
let statusBarFrame: CGRect
if #available(iOS 13.0, *) {
statusBarFrame = view.window?.windowScene?.statusBarManager?.statusBarFrame ?? CGRect.zero
} else {
statusBarFrame = UIApplication.shared.statusBarFrame
}
let statusBarView = UIView(frame: statusBarFrame)
statusBarView.backgroundColor = backgroundColor
view.addSubview(statusBarView)
}
}

Xcode 12 +

You can change it with YourProject.xcodeproj file in General Tab there is option to chnage status bar color you can set dark light or default with this option Thanks.

enter image description here