如何在iOS 7上更改状态栏的背景颜色和文本颜色?


88

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

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

因此,我无法区分状态栏和导航栏。

如何使状态栏看起来与iOS 5和6相同,即黑色背景颜色和白色文本颜色?如何以编程方式执行此操作?


:你可以得到帮助,这个环节 stackoverflow.com/questions/18901753/...
Utkarsh戈埃尔

Answers:


174

警告:它在iOS 13和Xcode 11上不再起作用。

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

我不得不尝试寻找其他方式。哪个不涉及addSubview窗口。因为在显示键盘时我正在向上移动窗口。

物镜

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

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

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

迅速

func setStatusBarBackgroundColor(color: UIColor) {

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

    statusBar.backgroundColor = color
}

迅捷3

func setStatusBarBackgroundColor(color: UIColor) {

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

    statusBar.backgroundColor = color
}

致电此表格application:didFinishLaunchingWithOptions对我有用。

注意:我们在应用商店中有一个具有此逻辑的应用。因此,我认为应用商店政策还可以。


编辑:

使用风险自负。形成评论者@Sebyddd

我有一个应用拒绝了这个原因,而另一个被接受就很好了。他们的确将其视为私有API的用法,因此在审核过程中您会很幸运:) – Sebyddd


5
与公认的解决方案不同,这在您更改方向时也适用。谢谢!
迈克尔

5
那不是私有API的用法吗?
Foriger

2
我有一个应用拒绝了这个原因,而另一个被接受就很好了。他们确实认为这是私有API的用法,所以您可能会在审核过程中
遇到麻烦

3
此解决方案存在一个问题,当您双击主屏幕按钮时,此状态栏颜色将消失。
永恒的

3
在iOS 13上不起作用。在UIApplication上名为-statusBar或-statusBarWindow的应用程序:必须更改此代码,因为不再有状态栏或状态栏窗口。而是在窗口场景上使用statusBarManager对象。
NSDeveloper

109

转到您的应用程序info.plist

1)设置View controller-based status bar appearanceNO
2)设置Status bar styleUIStatusBarStyleLightContent

然后转到您的应用程序委托,并将以下代码粘贴到您设置Windows的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];
}

希望能帮助到你。


刚刚提到,苹果文档推荐使用if if代替:if(NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1){} else {}很高兴!
乔尔·巴尔默

2
@learner转到info.plist,然后选择任何行。您会看到一个+号。单击加号,然后从下拉菜单中,您将看到Status bar style选项。选择它。并粘贴UIStatusBarStyleLightContent为它的价值。
沙希德·伊克巴尔

5
这种不考虑旋转
lostintranslation

4
最好使用UIScreen宽度:UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 20)];
KlimczakM 2015年

2
设置框架的更简洁方法是使用UIApplication.sharedApplication().statusBarFrame
Doug

28

在iOS 7中处理状态栏的背景色时,有2种情况

情况1:使用导航栏查看

在这种情况下,请在viewDidLoad方法中使用以下代码

 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];

情况2:没有导航栏的视图

在这种情况下,请在viewDidLoad方法中使用以下代码

 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];

源链接http://code-ios.blogspot.in/2014/08/how-to-change-background-color-of.html


这对我来说效果很好,但是状态栏应该高20pt:[[UIView alloc] initWithFrame:CGRectMake(0,-20,320,20)];
LordParsley

27

1)在plist中将UIViewControllerBasedStatusBarAppearance设置为YES

2)在viewDidLoad中做一个 [self setNeedsStatusBarAppearanceUpdate];

3)添加以下方法:

 -(UIStatusBarStyle)preferredStatusBarStyle{ 
    return UIStatusBarStyleLightContent; 
 } 

更新:
还检查开发人员指南到iOS 7状态栏


您可以将其更改为黑色或白色
Muruganandham K

1
这无效(ios7,模拟器)。永远不会调用“ preferredStatusBarStyle”。
亚当

1
您在使用xib吗?如果是,则更改模拟指标属性中的状态栏值
Muruganandham K 2013年

3
啊,我发现了问题。苹果的UINavigationController捕获通知-即您的答案仅适用于视图控制器为顶部控制器,没有容器(没有标签栏,没有导航栏等)的情况。
亚当

3
使用Storyboard + NavigationController时的特殊情况。执行上面的#1。接下来,为UINavigationController创建一个子类(称为myNavController)。在情节提要中,将NavigationController的类设置为“ myNavController”。在myNavController.m中,执行上面的#2和#3。现在将在您的子类中调用#3中的方法(设置要观察的日志或断点)。
ObjectiveTC

16

您可以在应用程序启动或视图控制器的viewDidLoad期间为状态栏设置背景颜色。

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
    }

}



结果如下:

在此处输入图片说明


这是有关状态栏更改的Apple准则/说明。状态栏中仅允许使用深色和浅色(白色和黑色)。

这是-如何更改状态栏样式:

如果要设置状态栏样式,请设置应用程序级别 UIViewControllerBasedStatusBarAppearanceNO在“ .plist”文件中将。

如果要设置状态栏样式,请在视图控制器级别执行以下步骤:

  1. UIViewControllerBasedStatusBarAppearanceYES.plist文件,如果需要设置状态栏样式仅UIViewController的水平。
  2. 在viewDidLoad中添加功能- setNeedsStatusBarAppearanceUpdate

  3. 在您的视图控制器中重写preferredStatusBarStyle。

--

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

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

如果我们使用这些应用,会否被拒绝?是否可以像这样更改statusBarView的颜色?
abhimuralidharan

@ abhi1992我不能说苹果是否会接受它,因为我在企业应用程序中实现了此解决方案,该应用程序不需要在App Store上提交。:)
克鲁纳尔

如果我将其放在基于选项卡的应用程序的viewcontroller的viewdidload中,它将为每个viewController设置颜色,而不仅仅是为我放置代码的那个设置(这是正常的吗?)

14

在iOS 7中,状态栏没有背景,因此,如果在其后面放置20px高的黑色视图,则将获得与iOS 6相同的结果。

另外,您可能需要阅读《iOS 7 UI过渡指南》以获取有关该主题的更多信息。


2
Gabriele,能否请您提供代码,该代码如何在其后面放置20px高视点?
Dejell 2013年

Dejel,这就是Shahid的答案。
Fattie 2014年

不要只使用“ 20”!您可以正确获取值,请参阅下面的详细答案。
Fattie

8

在您的ViewDidLoad方法中编写此代码:

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

它在一定程度上为我和其他UI错位修复了状态栏颜色。


7

这是一个完整的复制和粘贴解决方案,其中包括

绝对正确的解释

涉及的每个问题。

感谢Warif Akhand Rishi

有关keyPath的惊人发现statusBarWindow.statusBar。好一个

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
}

6

只是为了补充Shahid的答案-您可以使用以下方法(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];
  ...
}

是的,这甚至更好地处理屏幕尺寸和方向。还在此代码周围添加类似以下内容:if(NSFoundationVersionNumber> NSFoundationVersionNumber_iOS_6_1)
Benjamin Piette

6

对于背景,您可以轻松地添加视图,例如:

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];

其中“ navbar”是UINavigationBar。


4
您的前两行是正确的。但是最后一行应为[navigationController.view addSubview:view]; 应该将其添加到UINavigationController的视图内而不是UINavigationBar的视图内,因为它将在20像素的状态栏(不与状态栏重叠)之后添加视图。
Shahid Iqbal 2014年

在Swift中使用以下代码:let rect = CGRect(x:0,y:0,width:UIScreen.main.bounds.width,height:UIApplication.shared.statusBarFrame.height)let bar = UIView(frame:rect)bar.backgroundColor = UIColor.white navigationController?.view.addSubview(bar)
JVS

5

斯威夫特4:

//更改状态栏的背景色

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

statusBar?.backgroundColor = UIColor.red

4

更改状态栏的背景颜色:Swift:

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

1

如果是iOS 9上的swift 2.0

将以下内容放在应用程序委托的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)

这行得通,但我认为这并不是处理这种样式的最佳方法
Michael

1

iTroid23解决方案为我工作。我错过了Swift解决方案。因此,这可能是有帮助的:

1)在我的plist中,我必须添加以下内容:

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

2)我不需要调用“ setNeedsStatusBarAppearanceUpdate”。

3)我必须迅速将其添加到我的UIViewController中:

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

感谢“ UIViewControllerBasedStatusBarAppearance”键,对我
有所

1

如果您使用UINavigationController,则可以使用如下扩展名:

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)
    }
}

它基本上使导航栏背景透明,并使用另一个UIView作为背景。您可以调用setNavigationBarBackground导航控制器的方法来设置导航栏背景色和状态栏。

请记住,setNavigationBar(hidden: Bool, animated: Bool)当您要隐藏导航栏时,必须使用扩展中的方法,否则用作背景的视图仍然可见。


对我来说,这是最好的答案,因为它缓解了许多其他答案问题。缺点是固定的frame.size.height = 64这是错误的。另一种获取高度的方法是-> .view.window?.windowScene?.statusBarManager?.statusBarFrame.height?0.
贡萨洛·加斯帕

1

试试这个。在您的appdelegate类didFinishLaunchingWithOptions函数中使用以下代码:

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

1

以下代码段应与目标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
      }
  }

你会得到双倍状态栏上的iOS 13
科林

0

对于条形颜色:您为条形提供自定义背景图像。

对于文本颜色:使用关于iOS中的文本处理中的信息


1
这与设置文本颜色
无关

如果只想设置纯色,添加背景图像是一个过大的选择,这是不可行的,尤其是如果您希望能够即时更改颜色
halil_g

0

我成功地自定义了StatusBar颜色,方法很简单AppDelegate.cs

public override bool FinishedLaunching(UIApplication app, NSDictionary options)

下一个代码:

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

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

因此,您得到的是这样的:

在此处输入图片说明

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


这是什么语言?
Ahmadreza

1
@Alfi Xamarin形成并在后台生成其C#
Dan

0

斯威夫特4

Info.plist添加此属性

查看基于控制器的状态栏外观为“否”

然后在AppDelegate里面didFinishLaunchingWithOptions添加这些代码行

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

0

在Swift 5和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
   }
})

在这里,我修复了状态栏背景色和导航栏背景色。如果您不想导航栏颜色对其进行注释。


0

SWIFT代码

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

0

对于iOS 13 *和Swift 4,您可以像下面那样使用。

1->将基于View控制器的状态栏外观设置为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
    }
}

在didFinishLaunchingWithOptions中使用

UIApplication.shared.statusBarView?.backgroundColor = UIColor.red
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.