在iOS8中使用Swift更改特定ViewController的状态栏颜色


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

对我来说,在任何ViewController中使用以上代码将特定ViewController的statusBar颜色设置为White都不起作用。有什么建议?使用UIApplication.sharedApplication方法,颜色会在整个应用程序的Info.plist中进行必要的更改之后更改。

// Change the colour of status bar from black to white
UIApplication.sharedApplication().statusBarStyle = .LightContent

如何仅更改某些必需的特定ViewController的状态栏颜色?

Answers:


348

阅读所有建议并尝试了一些方法之后,我可以使用以下步骤将此方法用于特定的视图控制器:

第一步:

打开info.plist,然后将名为“ 基于视图控制器的状态栏外观 ” 的新密钥插入NO。

第二步(仅作说明,无需实施):

通常,我们将以下代码放入AppDelegate的application(_:didFinishLaunchingWithOptions :)方法中,

迅捷2

UIApplication.sharedApplication().statusBarStyle = .LightContent

迅捷3

UIApplication.shared.statusBarStyle = .lightContent

但这会影响statusBarStyle所有的ViewController。

因此,如何使它适用于特定的ViewController-最后一步:

打开您要更改的viewcontroller文件,statusBarStyle然后将以下代码放入中viewWillAppear()

迅捷2

UIApplication.sharedApplication().statusBarStyle = .LightContent

迅捷3

UIApplication.shared.statusBarStyle = .lightContent

另外,viewWillDisappear()为该特定的viewController 实现方法,并放入以下代码行,

迅捷2

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.Default

}

迅捷3

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    UIApplication.shared.statusBarStyle = UIStatusBarStyle.default
}

此步骤将首先更改statusBarStyle特定ViewController的,然后将其更改回default特定ViewController消失的时间。不执行viewWillDisappear()statusBarStyle永久更改为的新定义值UIStatusBarStyle.LightContent


4
请注意,如果Status bar is initially hidden = YES在info.plist文件中进行设置,则“基于视图控制器的状态栏外观=否”将导致状态栏被隐藏。
xi.lin

13
如果要改回UIStatusBarStyle.Defaultusing viewWillDisappear(),则应使用viewWillAppear()它来初始化它,而不是viewDidLoad()....否则,如果返回该视图而不必重新加载它,则不会看到StatusBarStyle期望的视图。
William GP

7
对于Swift 3: UIApplication.shared.statusBarStyle = .lightContent
ibrahimyilmaz

4
尚不清楚如何更改状态栏的颜色
DoruChidean

4
伙计们,它已从iOS 9弃用
Jeevan

108

(截至2019年9月20日)

迅捷5迅捷4.2迅捷4

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    setNeedsStatusBarAppearanceUpdate()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
    .lightContent
}

7
请确保调用super.viewWillAppear,如果你复制和粘贴代码
斯蒂芬·西尔伯

编辑为包含super.viewWillAppear()。感谢@StephenSilber的提示!
BennyTheNerd

您必须覆盖preferredStatusStyle,否则它将无法正常工作。感谢您指出了这一点。+1
Alix

3
UIApplication.shared.statusBarStyle = .lightContent在此编译器中使用结果警告:iOS 9.0中已弃用'statusBarStyle'的设置方法:使用-[UIViewController preferredStatusBarStyle]
播出

3
在应用程序的Info.plist中,将“基于视图控制器的状态栏外观”设置为YES
IvanPavliuk

29

我遵循了本教程,它对我有用。但是,我不确定是否有任何警告。

https://coderwall.com/p/dyqrfa/customize-navigation-bar-appearance-with-swift

  • 打开info.plist并设置 UIViewControllerBasedStatusBarAppearancefalse
  • 在中的第一个功能AppDelegate.swift(其中包含)中didFinishLaunchingWithOptions,设置所需的颜色。

UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent

  • Swift 3更新 *

    UIApplication.shared.statusBarStyle = .lightContent


11
每个视图控制器的具体
含义

4
确实,这是针对完整的应用程序的,这不是问题。
Anuj 2015年

3
我正在使用iOS 8 Swift和xCode 6.1.1,仅遵循以下两个步骤是行不通的。您还需要添加UIApplication.sharedApplication().statusBarHidden = false到AppDelegate.swift didFinishLauchingWithOptions
Ahmad Amin

这为整个应用程序设置了它。对于特定的视图控制器,请参阅第一个答案。它为我工作。
Akshar Patel

iOS 9.0中已弃用“ statusBarStyle”的设置器:使用-[UIViewController preferredStatusBarStyle]
Oleksandr

29

使用NavigationController的Swift 4.2解决方案

第一步:

打开你的info.plist并插入一个名为“新键查看基于控制器的状态栏外观 ”或UIViewControllerBasedStatusBarAppearanceYES让每个VC用自己的状态属性。

第二步

在每个VC中,都应像这样重写preferredStatusBarStyle属性:

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent //.default for black style
}

最后一步

覆盖自定义NavigationController类中的preferredStatusBarStyle属性:

class NavigationController : UINavigationController {

override var preferredStatusBarStyle : UIStatusBarStyle {

    if let topVC = viewControllers.last {
        //return the status property of each VC, look at step 2
        return topVC.preferredStatusBarStyle  
    }

    return .default
}

这只是使用导航控制器和您自己的控制器达到预期结果的方式。您也可以像我对项目所做的那样为preferredStatusBarHidden这样操作:)
atereshkov

22

这里有十亿个答案,所以我想为什么不以扩展名的形式添加另一个(在@Cœur的帮助下)

迅捷3

延期:

extension UIApplication {
    class var statusBarBackgroundColor: UIColor? {
        get {
            return (shared.value(forKey: "statusBar") as? UIView)?.backgroundColor
        } set {
            (shared.value(forKey: "statusBar") as? UIView)?.backgroundColor = newValue
        }
    }
}

实现方式:

UIApplication.statusBarBackgroundColor = .blue

2
请注意,该方法可能被视为访问私有API,并且可能意味着您的应用将被Apple拒绝。
JWhitey

或者至少它取决于Apple的实现细节,并且可能会因iOS的更改而在没有警告的情况下中断。
克里斯·普林斯

19

在您的Info.plist中,您需要将基于View控制器的状态栏外观定义为任何值。

如果将其定义为YES,则应在每个视图控制器中重写preferredStatusBarStyle函数。

如果您将其定义为否,则可以使用以下方法在AppDelegate中设置样式

UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)

7
setStatusBarStyle在iOS 9.0中已弃用
Jeffrey Neo

@Jeffrey_Neo虽然的确如此,但我无法让替代者正常工作。将您的评论作为工作代码的答案将很有用。
dumbledad '16

15
override func viewWillAppear(animated: Bool) {
    self.navigationController?.navigationBarHidden =  true

    UIApplication.sharedApplication().statusBarHidden = false
    UIApplication.sharedApplication().statusBarStyle = .LightContent

    let statusBar: UIView = UIApplication.sharedApplication().valueForKey("statusBar") as! UIView
    if statusBar.respondsToSelector("setBackgroundColor:") {
        statusBar.backgroundColor = UIColor.redColor()
    }

}

使用valueForKey("statusBar")可能不符合苹果的指导方针
心教堂

15

迅捷3

let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
if statusBar.responds(to: #selector(setter: UIView.backgroundColor)) {
  statusBar.backgroundColor = UIColor.black
} 

这是为特定视图控制器设置状态栏的背景色的解决方案。


3
UIView始终在Swift中响应backgroundColor。
心教堂

13

SWIFT 2

通过在viewWillAppear中添加以下内容,我能够成功更改状态栏背景的外观:

let statusBar: UIView = UIApplication.sharedApplication().valueForKey("statusBar") as! UIView

    if statusBar.respondsToSelector(Selector("setBackgroundColor:")) {
        statusBar.backgroundColor = .redColor()
    }

10

实现preferredStatusBarStyle您拨打所提及 self.setNeedsStatusBarAppearanceUpdate()ViewDidLoad,并在Info.plist中集UIViewControllerBasedStatusBarAppearanceYES(这是YES默认情况下)

目前尚不清楚为什么它无法正常工作。我需要检查代码。另一个建议是将正常工作的代码放入其中,viewDidLoad UIApplication.sharedApplication().statusBarStyle = .LightContent并在视图消失时将其更改为默认值viewWillDisappear


只是实施答案的第一部分对我有用。但是,我没有在Info.plist中添加UIViewcontrollerBasedStatusBarAppearance。它仍然有效。
Akshar Patel

10

迅速3

.plist

View controller-based status bar appearance = NO

AppDelegate.swift

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Custom statubar
        UIApplication.shared.isStatusBarHidden = false
        UIApplication.shared.statusBarStyle = .lightContent
        let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
        statusBar.backgroundColor = UIColor.gray

        return true
    }

1
我尝试了所有解决方案...这只对我有用!我不知道为什么:D
Khaled Hayek '18

抽奖的好运
Giang

'isStatusBarHidden'的设置方法在iOS 9.0中已被弃用:使用-[UIViewController preferredsStatusBarHidden] ...
提请。

9

在我的情况下,我使用情节提要来组织我的视图控制器。我想更改所有状态栏样式。

您可以在下面的图片中看到。

在此处输入图片说明

StarsView Controller是的子类CPBaseNavigationController,并且CPBaseNavigationController是的子类UINavigationController

我尝试进行下一个步骤:

  1. AppDelegate.swiftfunc中didFinishLaunchingWithOptions,添加

    //change status bar color
    UIApplication.sharedApplication().statusBarHidden = false
    UIApplication.sharedApplication().statusBarStyle = .LightContent

    但没有效果。

  2. 在StoryBoard中,找到Base Tab BarController(上面的图片)。选择Attributes Inspector,将Sattus Bar属性更改为Light Content.so bad,没有效果。

在此处输入图片说明

  1. 最后我明白了。在我的自定义导航控制器中CPBaseNavigationController,添加funcpreferredStatusBarStyle

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

    效果很好!

此外,statusBarStyle在9.0中已弃用,您可以使用-[UIViewController preferredStatusBarStyle]


9

适用于基于导航的应用程序

    var addStatusBar = UIView()
    addStatusBar.frame = CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, 20);
    addStatusBar.backgroundColor = global().UIColorFromRGB(0x65b4d9)
    self.window?.rootViewController?.view .addSubview(addStatusBar)

在哪里添加此特定代码,只是无法使其正常工作。
Anuj 2015年

您可以将其添加到didFinishLaunchingWithOptions中的App委托文件中
Jio

1
使用addStatusBar.frame = CGRectMake(0,0,UIScreen.mainScreen()。bounds.width,20)代替硬编码的320宽度会更好吗?
Torsten Ojaperv '16

@TorstenOjaperv编辑
Jio

swift 3.0怎么做?
YETI

8

在Swift 3.0 Xcode 8中一切都变得更加容易

之后,在App Delegate文件中使用以下代码

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

插入此:

UINavigationBar.appearance().barStyle = .black

UINavigationBar.appearance().barTintColor = UIColor(red: 230, green: 32, blue: 31, alpha: 1.0)

1
红色,绿色和蓝色值的范围是0到1。您必须将它们除以255,否则将不起作用。
Makalele,2017年

8

迅捷3

//
//  LoginController.swift
//  Swift 3
//
//  Created by The Crab on 17/01/2017.
//  Copyright © 2017 Paxi Labs. All rights reserved.
//

import UIKit

class LoginController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        setNeedsStatusBarAppearanceUpdate()

        view.backgroundColor = UIColor(red: 61/255, green: 91/255, blue: 151/255, alpha: 1)

    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
}

7

Swift 4对于未嵌入navigationViewController的特定ViewController,只需将其添加到您的ViewController文件中。

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}

如果我们嵌入了导航控制器,您将怎么办?
icekomo

7

进行此工作的另一种非常简单的方法是创建UINavigationController类的扩展。

由于重写该preferredStatusBarStyle:方法将无法工作,除非我们在UINavigationController类中进行此操作。

    extension UINavigationController {
        open override var preferredStatusBarStyle: UIStatusBarStyle {
            return .lightContent
        }
    }

4

我使用App Delegate文件中的以下代码设置了特定的颜色(以RGB格式):

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
. . .

 UIApplication.sharedApplication().statusBarHidden = false
        UIApplication.sharedApplication().statusBarStyle = .LightContent

        let statusBar: UIView = UIApplication.sharedApplication().valueForKey("statusBar") as! UIView
        if statusBar.respondsToSelector(Selector("setBackgroundColor:")) {
            statusBar.backgroundColor = UIColor.init(red: 0.1, green: 0.27, blue: 0.60, alpha: 1.0)
        }

. . .
}

您还需要在Info.plist文件中添加以下密钥:

查看基于控制器状态栏的状态,布尔值设置为NO

屏幕截图1

屏幕截图2


使用Siwft 3.0,该怎么做?
YETI

4

我可以建议您一种更简单的方法,

  1. 如Apple文档所述,只需在viewDidLoad中调用setNeedsStatusBarAppearanceUpdate

如果视图控制器的状态栏属性(例如,隐藏/未隐藏的状态或样式)发生更改,则调用此方法。如果在动画块中调用此方法,则所做的更改将与动画块的其余部分一起进行动画处理。

  1. 实现preferredStatusBarStyle返回您的首选类型。

它在iOS 10.1中对我有用。

目标C

[self setNeedsStatusBarAppearanceUpdate];

-(UIStatusBarStyle)preferredStatusBarStyle {
     return UIStatusBarStyleLightContent;
}

迅速

setNeedsStatusBarAppearanceUpdate()

var preferredStatusBarStyle: UIStatusBarStyle { 
    return .lightContent
}

我很惊讶没有人指出这一点。无论如何享受:)


4

我对此有些麻烦。我对全局更改状态栏颜色确实不满意,但确实像接受的答案一样消失了。信不信由你,您可以通过覆盖preferredStatusBarStyle所需的视图控制器来使此工作正常。经过很多时间,这就是我要做的工作:

  1. 将您的基于View控制器的状态栏外观更改info.plist为YES。
  2. 现在,任何全屏视图控制器都可以通过重写来更改状态栏的样式preferredStatusBarStyle
  3. 我指定全屏,因为这不适用于(非全屏)模式视图控制器,并非没有设置modal​Presentation​Captures​Status​Bar​Appearance为“是”。
  4. 同样,如果您嵌入了视图控制器,例如在导航控制器中,它将向最顶部的视图控制器询问状态栏样式。覆盖child​View​Controller​For​Status​Bar​Style并传递嵌入式视图控制器应该可以工作,但对我而言却不是。因此,我只是将嵌入式视图控制器的首选状态栏作为首选状态栏样式返回了。像这样:

    override var preferredStatusBarStyle: UIStatusBarStyle {
         if let topViewController = viewControllers.last {
             return topViewController.preferredStatusBarStyle
         }
    
         return .default
    }

这个答案帮助了我!我发现由于某种原因,我的导航控制器(以模态形式显示)并未隐式地向最顶层的视图控制器询问其状态栏样式。所以我不得不继承UINavigationController并重写其中的child​View​Controller​For​Status​Bar​Stylevar,返回self.topViewController
taber

3

在Swift 4或4.2中

您可以在vc上添加

preferredStatusBarStyle

并将返回值设置为

.lightContent或.default

例如:

override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
}

3

(截至2020年6月10日)

Swift 5不编辑.Plist文件

如果您正在使用Storyboard,请转到NavigationController,选择navigationBar,单击Attributes Inspector,然后更改style。如果需要light content白色状态栏)进行设置,除了default可以说设置样式black,如果需要dark content黑色状态栏)进行设置default

默认(UIBarStyleDefault)会导致前景UIStatusBarStyleDefault状态栏变暗。并UIBarStyleBlack会给出一个UIStatusBarStyleLightContent状态栏。

以编程方式

let nav = UINavigationController(rootViewController: rootViewController)

    nav.navigationBar.barStyle = .default //gives you dark Content status bar

    nav.navigationBar.barStyle = .black  //gives you light content status bar

没有导航栏编辑.Plist

添加到UIViewControllerBasedStatusBarAppearance/ ,设置值为。View controller-based status bar appearanceinfo.plisttrue

OverridepreferredStatusBarStyle控制器中的属性

class ViewController: UIViewController {
    override var preferredStatusBarStyle : UIStatusBarStyle {
        return .lightContent
    }
}

2

Swift 3.0更新

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

        UIApplication.shared.statusBarStyle = .lightContent

        return true
    }

2

与我合作的方法是,在情节提要中,转到导航控制器,选择导航栏,单击“属性”检查器,然后将样式从默认更改为黑色。而已!


2

SWIFT 4.2 嘿,我想分享一个解决方案,该解决方案对我有用,是我从Graig Grummitt撰写的一篇关于这个难以捉摸的话题的出色文章中获得的。

步骤1正如其他人提到的,将以下添加到您的PLIST

View controller-based status bar appearance YES

RootViewcontroller中的第2步在下面添加

var statusBarHidden: Bool = false {
        didSet(newValue) {
            UIView.animate(withDuration: 0.1) {
                self.setNeedsStatusBarAppearanceUpdate()
            }
        }
    }

    override var prefersStatusBarHidden: Bool {
        return statusBarHidden
    }

    var vcStatusBarStyle: UIStatusBarStyle = .default {
        didSet(newValue) {
            UIView.animate(withDuration: 0.1) {
                self.setNeedsStatusBarAppearanceUpdate()
            }
        }
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return vcStatusbarStyle
    }

当更新这两个属性statusBarHidden或者vcStatusBarStyle它会调用setNeedsStatusBarAppearanceUpdate(),并且将更新为新值状态栏的两种prefersStatusBarHiddenpreferredStatusBarStyle。在我的情况下,我必须为容器viewcontroller更新这些属性,该属性是可见childviewcontroller的父级。我使用简单的委托方法进行了此操作。

protocol MainViewControllerDelegate {
    func updateStatusBarStyle(statBarStayle: UIStatusBarStyle)
    func toggleStatusBar(visable: Bool)
}

当然,在实例化childViewController(Visible VC)时,请不要忘记将MainViewcontroller(Container VC)设置为其委托。我有时会。:)

childViewController.delegate = self

然后在childViewController中,当需要更新状态栏时,我只是调用了委托方法。

self.delegate?.updateStatusBarStyle(statBarStayle: .default)

如上所述,Graig Grummitt详细介绍了此解决方案,并且还与UINavigationControllers一起使用。链接到这里:状态栏的神秘案例


1

单击“支持文件”组(左侧顶部-项目名称)。导航到信息。在列表之间的某处单击+,例如捆绑名称下方。并添加“基于View Controller的状态栏外观”并将其设置为NO。然后打开AppDelegate.swift并进行如下修改:

func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {

UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)

return true
}

而已。


您看错了这个问题。我问过如何更改特定ViewController而不是整个应用程序的StatusBarStyle。
Anuj 2015年

请在下面查看我的答案@Anuj
theCrab

1

对于Xcode 10,您可以创建一个类并将其放在viewController类之前,可以在所有需要光内容状态栏的视图控制器中调用该类。

class UIViewControllerWithLightStatusBar: UIViewController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return UIStatusBarStyle.lightContent
}
}

现在,在以下位置更改viewController类:

class YourViewController: UIViewControllerWithLightStatusBar {
...
}

就这样...


1

swift4中基于导航的特定视图控制器的作品

   let app = UIApplication.shared
   let statusBarHeight: CGFloat = app.statusBarFrame.size.height

   let statusbarView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: statusBarHeight))
   statusbarView.backgroundColor = UIColor.red
   view.addSubview(statusbarView)

1

警告


iOS 9.0中已弃用“ statusBarStyle”的设置器:使用-[UIViewController preferredStatusBarStyle]

UIApplication.shared.statusBarStyle = .default

所以我的解决方案是这样的:从导航控制器进行扩展:

extension UINavigationController {
    open override var preferredStatusBarStyle: UIStatusBarStyle {
        if let topViewController = presentedViewController{
            return topViewController.preferredStatusBarStyle
        }
        if let topViewController = viewControllers.last {
            return topViewController.preferredStatusBarStyle
        }

        return .default
    }
}

如果您的viewController的样式会不同于应用程序的样式,则可以

var barStyle = UIStatusBarStyle.lightContent
override var preferredStatusBarStyle: UIStatusBarStyle{
    return barStyle
}

假设您的应用程序状态样式为,.default并且您希望此屏幕显示为.lightContent barStyle .lightContent的默认值,这会将状态栏样式更改为lightContent,然后确保何时viewWillDisappear将barStyle再次更改为应用程序状态栏样式在我们的情况下是.default

这对我有用


1

状态栏的自定义颜色(iOS11 +,Swift4 +)

如果您正在寻找解决方案,如何将状态栏更改为自定义颜色,这是可行的解决方案。

let statusBarView = UIView()
view.addSubview(statusBarView)
statusBarView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    statusBarView.topAnchor.constraint(equalTo: view.topAnchor),
    statusBarView.leftAnchor.constraint(equalTo: view.leftAnchor),
    statusBarView.rightAnchor.constraint(equalTo: view.rightAnchor),
    statusBarView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
])
statusBarView.backgroundColor = .blue
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.