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

问题描述 投票:159回答:31
override func preferredStatusBarStyle() -> UIStatusBarStyle {
 return UIStatusBarStyle.LightContent;
}

在任何ViewController中使用上面的代码将statusBar颜色设置为White为特定的viewcontroller在iOS8中不起作用。有什么建议?使用UIApplication.sharedApplication方法,在整个应用程序的Info.plist中所需的更改之后,颜色会发生变化。

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

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

swift uiviewcontroller ios8 xcode6 statusbar
31个回答
331
投票

在阅读了所有建议并尝试了一些内容之后,我可以使用以下步骤将其用于特定的viewcontrollers:

第一步:

打开info.plist并将名为“View controller-based status bar appearance”的新密钥插入NO

第二步(只是一个解释,不需要实现这个):

通常我们将以下代码放在AppDelegate的应用程序(_:didFinishLaunchingWithOptions :)方法中,

斯威夫特2

UIApplication.sharedApplication().statusBarStyle = .LightContent

斯威夫特3

UIApplication.shared.statusBarStyle = .lightContent

但这会影响所有ViewControllers的statusBarStyle

那么,如何使这个特定的ViewControllers工作 - 最后一步:

打开要更改statusBarStyle的viewcontroller文件,并将以下代码放在viewWillAppear()中,

斯威夫特2

UIApplication.sharedApplication().statusBarStyle = .LightContent

斯威夫特3

UIApplication.shared.statusBarStyle = .lightContent

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

斯威夫特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,然后在特定视图控制器消失时将其更改回default。不实施viewWillDisappear()statusBarStyle永久更改为新定义的UIStatusBarStyle.LightContent


9
投票

对于斯威夫特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
    }

8
投票

如你所述实现preferredStatusBarStyle并在self.setNeedsStatusBarAppearanceUpdate()中调用ViewDidLoad,并在Info.plist中将UIViewControllerBasedStatusBarAppearance设置为YES(默认情况下为YES

目前尚不清楚为什么它不工作。我需要检查代码。另外一个建议是使用viewDidLoad UIApplication.sharedApplication().statusBarStyle = .LightContent中的工作代码并将其更改为默认值,当您查看get消失的viewWillDisappear时。


8
投票

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

你可以在下面看到。

enter image description here

Stars View Controller是一个CPBaseNavigationController,而CPBaseNavigationControllerUINavigationController的子类。

我尝试做下面的步骤:

  1. AppDelegate.swift func 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坏,没有效果。

enter image description here

  1. 最后我明白了。在我的自定义导航控制器CPBaseNavigationController中,添加func preferredStatusBarStyle override func preferredStatusBarStyle() -> UIStatusBarStyle { return .LightContent } 它运作良好!

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


7
投票

适用于导航应用

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

7
投票

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

7
投票

斯威夫特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
    }
}

6
投票

Swift 4对于没有使用navigationViewController嵌入的特定ViewController,只需将其添加到ViewController文件即可。

override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}

3
投票

我在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

Screenshot 1

Screenshot 2


2
投票

我可以建议你一个更简单的方法,

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

如果视图控制器的状态栏属性(例如隐藏/取消隐藏状态或样式)发生更改,请调用此方法。如果在动画块中调用此方法,则会将更改与动画块的其余部分一起设置动画。

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

它在iOS 10.1中适用于我。

目标C.

[self setNeedsStatusBarAppearanceUpdate];

-(UIStatusBarStyle)preferredStatusBarStyle {
     return UIStatusBarStyleLightContent;
}

迅速

setNeedsStatusBarAppearanceUpdate()

var preferredStatusBarStyle: UIStatusBarStyle { 
    return .lightContent
}

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


2
投票

我遇到这个问题。对于全局更改状态栏颜色在视图中确实显示并且然后将其更改回视图确实像已接受的答案一样消失时我感觉不太好。信不信由你,你可以通过覆盖所需视图控制器上的preferredStatusBarStyle来实现这一点。经过很长时间,这就是我所做的工作:

  1. 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 }

71
投票

(截至2019年3月14日)

Swift 4,Swift 4.2

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

1
投票

Swift 3.0更新

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

        UIApplication.shared.statusBarStyle = .lightContent

        return true
    }

1
投票

在Storyboard中,对我有用的是导航控制器,选择导航栏,单击属性检查器,然后将样式从默认更改为黑色。而已!


1
投票

另一个非常简单的方法就是创建UINavigationController类的扩展。

由于覆盖preferredStatusBarStyle:方法不会工作,除非我们在UINavigationController类中进行。

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

1
投票

在Swift 4或4.2中

您可以添加您的vc

preferredStatusBarStyle

并将返回值设置为

.lightContent或.default

例如:

override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
}

0
投票

单击Supporting Files组(左侧顶部 - 项目名称)。导航到信息。单击列表之间的某个位置,如下面的包名称。并添加“查看基于控制器的状态栏外观”并将其设置为NO。然后打开AppDelegate.swift并像这样修改:

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

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

return true
}

而已。


0
投票

我文学上也遇到了同样的问题。花了我4个多小时来搞清楚。我尝试了这里给出的所有答案,我得到的最好的是获得状态栏白色的标题。但是无论我做了什么,其他部分,如电池条和其他部分仍然是黑色的:关于应用此问题中提供的所有解决方案。所以我决定回溯我的步骤,并了解到我已经下载了一个CocoaPod依赖项,它改变了Xcode的正常功能和改变颜色的代码。对我来说,这是“ChameleonFramework”的依赖性。因此,如果您已应用所有解决方案并且不适合您,我建议您检查您从CocoaPods安装的依赖项,删除最新的依赖项。


0
投票

对于Xcode 10,您可以创建一个类并将其放在您的viewController类之前,您可以在所有视图控制器中调用此类,需要一个轻量级状态栏...

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

现在更改viewController类:

class YourViewController: UIViewControllerWithLightStatusBar {
...
}

就这样...


0
投票

SWIFT 4.2嘿,我想分享一个对我有用的解决方案,我从Graig Grummitt撰写的这篇关于这个特殊主题的精彩文章中得到了解决方案。

步骤1正如其他人在您的PLIST中提到的ADD

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
    }

更新属性statusBarHiddenvcStatusBarStyle时,它将调用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。链接在这里:The Mysterious Case of the Status Bar


0
投票

适用于导航基于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)

0
投票

警告


'statusBarStyle'的setter在iOS 9.0中已弃用:使用 - [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更改为app状态栏样式,在我们的例子中是.default

这对我有用


26
投票

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

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

  • 打开你的info.plist并将UIViewControllerBasedStatusBarAppearance设置为false
  • AppDelegate.swift的第一个函数中,它包含didFinishLaunchingWithOptions,设置你想要的颜色。

UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent

  • Swift 3更新* UIApplication.shared.statusBarStyle = .lightContent

-2
投票

斯威夫特3

AppDelegate文件里面的func application文件中

let statusBar: UIView = application.value(forKey: "statusBar") as! UIView
statusBar.backgroundColor = .red

17
投票

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

斯威夫特3

Extension:

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

Implementation:

UIApplication.statusBarBackgroundColor = .blue

16
投票

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

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

如果您将其定义为NO,则可以使用AppDelegate设置样式

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

15
投票

带NavigationController的Swift 4.2解决方案

第一步:

打开info.plist并插入名为“View controller-based status bar appearance”或UIViewControllerBasedStatusBarAppearance的新密钥为YES,让每个VC使用自己的status属性。

第二步

在每个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
}

14
投票
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()
    }

}

12
投票

SWIFT 2

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

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

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

12
投票

斯威夫特3

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

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

© www.soinside.com 2019 - 2024. All rights reserved.