首页 文章

如何在Swift 3中设置状态栏样式

提问于
浏览
143

我正在使用Xcode 8.0 beta 4 .

在以前的版本中,UIViewController具有设置状态栏样式的方法

public func preferredStatusBarStyle() -> UIStatusBarStyle

但是,我发现它在Swift 3中改为“Get ONLY varaiable” .

public var preferredStatusBarStyle: UIStatusBarStyle { get }

如何在我的UIViewController中提供使用的样式?

28 回答

  • 90

    这些答案中的大多数都是重新散列的,但在使用深色背景时,它们都没有真正解决我的启动画面问题 .

    我在 info.plist 中使用以下内容解决了这个问题,它产生了一个轻薄的状态栏 .

    <key>UIStatusBarStyle</key>
    <string>UIStatusBarStyleLightContent</string>
    
  • 0

    This is the preferred method for iOS 7 and higher

    在应用程序的 Info.plist 中,将"View controller-based status bar appearance"设置为YES .

    Override preferredStatusBarStyle in each of your view controllers . 例如:

    override var preferredStatusBarStyle: UIStatusBarStyle {     
          return .lightContent
    }
    

    如果 preferredStatusBarStyle 根据视图控制器内部更改的内容返回不同的首选状态栏样式(例如,滚动位置或显示的图像是否较暗),那么当该状态发生变化时,您将需要调用 setNeedsStatusBarAppearanceUpdate() .

    如果使用导航控制器并且希望使用每个视图控制器的首选状态栏样式,请参阅https://stackoverflow.com/a/41026726/1589422 .

    iOS before version 7, deprecated method

    Apple has deprecated this,因此将来会被删除 . 使用上面的方法,以便在下一个iOS版本发布时不必重写它 .

    如果您的应用程序支持在您的应用程序的 Info.plist 中,请将"View controller-based status bar appearance"设置为NO .

    appDelegate.swiftdidFinishLaunchingWithOptions 函数中,添加:

    UIApplication.shared.statusBarStyle = .lightContent
    
  • -1

    Xcode 8.3.1,Swift 3.1

    • 在info.plist中创建一个新条目“查看基于控制器的状态栏外观”将其设置为“NO” .

    • 打开AppDelegate.swift并在“didFinishLaunchingWithOptions”方法中添加以下行:

    application.statusBarStyle = .lightContent

  • 25

    Swift 4.0请在“didFinishLaunchingWithOptions launchOptions:”Appdelegate类中使用此代码

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

    这对我有用

    View controller-based status bar 外观设置为plist中的 NO 然后在 UIViewController viewDidAppear 中添加以下行

    UIApplication.shared.setStatusBarStyle(UIStatusBarStyle.lightContent, animated: true)
    
  • 5

    您可以使用名为“shouldStatusBarDark”的bool属性来切换状态栏颜色 . 您还可以更新其值以在滚动时更改状态栏颜色 .

    var shouldStatusBarDark = false {
         didSet {
             setNeedsStatusBarAppearanceUpdate()
         }
     }
    
     override var preferredStatusBarStyle: UIStatusBarStyle {
         return shouldStatusBarDark ? .default : .lightContent
     }
    
     func scrollViewDidScroll(_ scrollView: UIScrollView) {
         let offSetY = scrollView.contentOffset.y
         if offSetY > 50 {
             UIView.animate(withDuration: 0.4, animations: {
                 self.navView.alpha = 1
                 self.shouldStatusBarDark = true
             })
         } else {
             UIView.animate(withDuration: 0.4, animations: {
                 self.navView.alpha = 0
                 self.shouldStatusBarDark = false
             })
         }
     }
    
  • 0

    我得到了:

    覆盖var必须与其封闭类型一样可访问

    通过添加 public 修复了这个问题:

    override public var preferredStatusBarStyle: UIStatusBarStyle {
        get {
            return .lightContent
        }
    }
    

    在Swift3 iOS10上 .

  • 4

    第一步,您需要添加一行键: View controller-based status bar appearance 和值 NOInfo.plist 文件 . 之后,在控制器中添加2个功能,只有控制器才能生效:

    override func viewWillAppear(_ animated: Bool) {
           super.viewWillAppear(animated)
           UIApplication.shared.statusBarStyle = .lightContent
    }
    
    override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            UIApplication.shared.statusBarStyle = .default    
    }
    
  • 124

    Swift 4+

    对于白色状态栏文本:

    navigationController.navigationBar.barStyle = .blackTranslucent
    
  • 5

    swift 3

    如果在Info.plist中查看基于控制器的状态栏外观= YES

    然后对所有NavigationController使用此扩展

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

    如果没有UINavigationController并且只有UIViewController,那么使用下面的代码:

    extension UIViewController
        {
            override open var preferredStatusBarStyle: UIStatusBarStyle {
            return .lightContent
             }
         }
    
  • 0

    处理导航栏时,状态栏文本颜色似乎有一个小问题 .

    如果要将.plist条目View基于控制器的状态栏外观设置为 YES ,则当您有彩色导航栏时,它有时不起作用 .

    例如:

    override func viewWillAppear(_ animated: Bool) {
        let nav = self.navigationController?.navigationBar
        nav?.barTintColor = .red
        nav?.tintColor = .white
        nav?.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
        setNeedsStatusBarAppearanceUpdate()
    }
    

    override var preferredStatusBarStyle: UIStatusBarStyle {return .lightContent}

    即使您在AppDelegate中设置了以下代码,上述代码也不起作用:

    UIApplication.shared.statusBarStyle = .lightContent

    对于那些仍在苦苦挣扎的人来说,显然它会以某种方式判断导航栏中的状态栏是否需要亮或暗 . 所以,我设法通过在viewWillAppear中添加以下行来解决这个问题:

    nav?.barStyle = UIBarStyle.black

    当条形样式为黑色时,它会侦听被覆盖的变量 . 希望这有助于某人:)

  • 3
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    

    这对我有用:)我的导航控制器嵌入在我的视图控制器中,隐藏了导航栏 . 我想在应用程序的某些视图上设置状态栏指示灯 .

  • 0

    使用WebkitView

    Swift 9.3 iOS 11.3

    import UIKit
    import WebKit
    
    class ViewController: UIViewController, WKNavigationDelegate, WKUIDelegate {
    
        @IBOutlet weak var webView: WKWebView!
        var hideStatusBar = true
    
        override func loadView() {
            let webConfiguration = WKWebViewConfiguration()
            webView = WKWebView(frame: .zero, configuration: webConfiguration)
            webView.uiDelegate = self
            view = webView
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.setNeedsStatusBarAppearanceUpdate()
            let myURL = URL(string: "https://www.apple.com/")
            let myRequest = URLRequest(url: myURL!)
            UIApplication.shared.statusBarView?.backgroundColor = UIColor.red
    
             webView.load(myRequest)
    
        }
    }
    
    extension UIApplication {
    
        var statusBarView: UIView? {
            return value(forKey: "statusBar") as? UIView
        }
    
    }
    
  • 0

    对于希望在所有视图控制器上更改状态栏的人:iOS 11,Swfit 4解决方案非常简单 .

    1) Info.plist add:

    查看基于控制器的状态栏外观 - >否

    2) XCode slect项目的左侧> Targets >选择项目>常规>部署信息>选择状态栏样式:光

    如果您只想为 one viewcontroller 更改状态栏,请在viewDidLoad上添加:

    override var preferredStatusBarStyle : UIStatusBarStyle {
        return .lightContent
    }
    
  • 11

    iOS 11.2

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
    
        UINavigationBar.appearance().barStyle = .black
    
        return true
    }
    
  • 4

    Swift 3

    要在应用程序中设置相同的导航栏外观,可以在AppDelegate.swift中执行此操作:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
            setupNavigationBarAppearence()
            return true
        }
    
    
    
    private func setupNavigationBarAppearence(){
            let navigationBarAppearace = UINavigationBar.appearance()
            navigationBarAppearace.isTranslucent = false
            //nav bar color
            navigationBarAppearace.barTintColor = UIColor.primaryColor()
            //SETS navbar title string to white
            navigationBarAppearace.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
            //Makes the batery icon an any other icon of the device to white.
            navigationBarAppearace.barStyle = .black
        }
    
  • 8

    您可以尝试覆盖返回的值,而不是设置它 . 该方法声明为,因此只需提供一个getter:

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    

    如果您有条件地设置此项,则需要调用 setNeedsStatusBarAppearanceUpdate() 以使'll animate the change when you'准备就绪

  • 22

    Swift 3 & 4, iOS 10 & 11, Xcode 9 & 10
    对我来说,这种方法不起作用:

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    

    当我习惯每个视图控制器,但这工作:

    • 在文件info.list中,添加行: View controller-based status bar appearance 并设置为 NO

    • appdelegate中的下一个:

    UIApplication.shared.statusBarStyle = .lightContent
    
  • 3

    Swift 3

    在Info.plist中添加一行名为"View controller-based status bar appearance"的行,并将其值设置为 No .

    class YourViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            UIApplication.shared.statusBarStyle = .lightContent //or .default
            setNeedsStatusBarAppearanceUpdate()
    
        }
    
    }
    
  • 2

    你也可以这样做这在故事板中

    • 在info.plist中创建一个新条目"View controller-based status bar appearance"将其设置为"YES" .

    • 转到故事板,然后选择要更改的导航控制器 . 单击Storyboard文档大纲部分的导航栏(故事板上的左侧面板)

    • 转到右侧面板,然后单击属性部分

    • 在导航栏部分下,您将看到样式 . 选择您想要的样式(默认为黑色,黑色为白色)

    您必须为每个导航控制器执行此操作 . 但是,该导航控制器下的任何视图都会将所有视图的状态栏样式/颜色更改为您刚刚选择的那个 . 我发现这个选项更好,因为你可以立即看到你的结果,而不必在每个视图控制器中添加额外的代码行 .

    enter image description here

    (在所有Swift项目中使用Xcode 8.3.3完成)

  • 91

    如果要将 statusBar 的颜色更改为白色,对于 UINavigationController 中包含的所有视图,请在 AppDelegate 中添加:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
    
        UINavigationBar.appearance().barStyle = .blackOpaque
        return true
    }
    

    这段代码:

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    

    does not 工作 UIViewControllers 包含 UINavigationController ,因为编译器查找 UINavigationControllerstatusBarStyle ,而不是查找 ViewControllersstatusBarStyle .

    希望这能帮助那些没有成功接受答案的人!

  • 0

    要添加到@Krunal https://stackoverflow.com/a/49552326/4697535的伟大asnwer

    如果您使用 UINavigationControllerpreferredStatusBarStyle 将对 UIViewController 无效 .

    Xcode 10 and Swift 4.

    设置自定义 UINavigationController

    Example:

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

    使用应用级解决方案的扩展程序:

    extension UINavigationController {
    
      open override var preferredStatusBarStyle: UIStatusBarStyle {
          guard let index = tabBarController?.selectedIndex else { return .default }
          switch index {
          case 0, 1, 2: return .lightContent // set lightContent for tabs 0-2
          default: return .default // set dark for tab 3
          }
      }
    }
    
  • 1

    最新更新(Xcode 10 / Swift 4.2)

    对于愿意理解过去几年中存在的不同方法背后的逻辑的人来说,本文保持不变 . 同时,从 Xcode 10, Swift 4.2 first approach is deprecated起不再支持(即 will not 如果您尝试使用它则生效) . 它仍然提供给您的信息,以便更好地理解 Plist.info 标志和定制实践背后的原因 .

    重要说明

    了解自定义状态栏外观的两种方法非常重要 . 它们是不同的,不应该混合 .

    第一种方法 - 整个应用程序的一种颜色(自iOS7以来已弃用)

    在info.plist中,您可以找到或创建一个名为的密钥

    View controller-based status bar appearance

    并将其设置为 NO .

    它能做什么?它基本上 Build 了一个设置,在您的应用程序中,状态栏外观 is not defined individually by each view controller . 理解这一点非常重要 . 这意味着您可以为整个应用程序设置统一设置,用于 all 屏幕 . 有两种设置: default ,在白色背景上为黑色文本,或 lightContent ,在黑色背景上为白色文本 .

    要设置其中一个( one setting for all screens ):

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        application.statusBarStyle = .lightContent // .default
        return true
    }
    

    这样,您无需在每个视图控制器上重新 Build 此设置 . 但是,您始终可以使用此方法自动更改外观 .

    第二种方法 - 每个视图控制器的单独颜色

    这是相反的 . 要使其工作,请继续info.plist并设置

    View controller-based status bar appearance

    YES

    这样,每当打开一个新的视图控制器时,如果在所需的每个 UIViewController 实例中插入此实现,则会单独设置状态栏样式:

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

    您与第一个相同,为状态栏设置暗或亮样式,为每个视图控制器设置个别 .

    第三种方法 - 哈克!

    有一个hack允许直接访问状态栏:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
        if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
            statusBar.backgroundColor = UIColor.blue
        }
    
        return true
    }
    

    为什么破解?如果您需要状态栏颜色而不是黑色或白色,则使用未记录的API . 使用KVC获取 statusBar 对象并设置其背景颜色 . 你通过这种方式获得的对象是 UIStatusBar ,它是从 UIView 派生的,因此自然支持 backgroundColor 属性 . 这是脏的,不合法的方式,但到目前为止,它是为状态栏设置自定义颜色的唯一方法(不考虑 UINavigationBar 方法,它允许完全自定义导航栏状态栏外观) . 它可能会导致您的应用被拒绝 . 但也许你很幸运 . 如果你是,在某些复杂情况下(如嵌套,子导航和视图控制器的层次结构),这可能是自定义状态栏外观的唯一或至少不那么麻烦的方式(例如,使其透明)

    Xcode 10+, Swift 4.2

    没有其他选择:开发人员应该让 each 视图控制器定义状态栏外观,方法是将标志设置为 YES (或省略此操作,因为默认情况下为YES)并遵循上述说明 .


    Bonus

    您可能(虽然不鼓励)在复杂环境中使用基于Hack的解决方案,以便在任何阶段自动更改状态栏外观 . 颜色方面,以下扩展方法完全按照常规方法完成 . 您可以根据自己的需要进行调整 .

    extension UIViewController {
        func setStatusBarStyle(_ style: UIStatusBarStyle) {
            if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
                statusBar.backgroundColor = style == .lightContent ? UIColor.black : .white
                statusBar.setValue(style == .lightContent ? UIColor.white : .black, forKey: "foregroundColor")
            }
        }
    }
    
  • 21

    请将以下行添加到info.plist中,然后才能实现

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

    并将以下代码段添加到您的代码中并查看输出

    UIApplication.shared.statusBarStyle = .lightContent
            UIApplication.shared.statusBarStyle = .default
    
  • 1

    这是关于状态栏样式更改的Apple Guidelines/Instruction .

    如果要设置状态栏样式,应用程序级别,请在 .plist 文件中将 UIViewControllerBasedStatusBarAppearance 设置为 NO . 并在您的 appdelegate > didFinishLaunchingWithOptions 添加以下ine(以编程方式,您可以从app delegate执行此操作) .

    Objective C

    [UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
    

    Swift

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        application.statusBarStyle = .lightContent
        return true
    }
    

    如果您要设置状态栏样式,请在视图控制器级别,然后按照下列步骤操作:

    • 如果需要仅在UIViewController级别设置状态栏样式,请将 UIViewControllerBasedStatusBarAppearance 设置为 .plist 文件中的 YES .

    • 在viewDidLoad中添加功能 - setNeedsStatusBarAppearanceUpdate

    • 覆盖视图控制器中的preferredStatusBarStyle .

    Objective C

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        [self setNeedsStatusBarAppearanceUpdate];
    }
    
    - (UIStatusBarStyle)preferredStatusBarStyle
    {
        return UIStatusBarStyleLightContent;
    }
    

    Swift

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setNeedsStatusBarAppearanceUpdate()
    }
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
    

    根据状态栏样式设置级别设置.plist的值 .

    enter image description here

  • 1

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

    View controller-based status bar appearance ,布尔值设置为 NO

    在你的appdelegate类中,在 didFinishLaunchingWithOptions 方法返回之前 .

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

    根据要求更改 backgroundColorstatusBarStyle .

  • 6

    如果要在视图出现后随时更改状态栏样式,可以使用以下命令:

    • 在文件info.list中添加行: View controller-based status bar appearance 并将其设置为 YES
    var viewIsDark = Bool()
    
    func makeViewDark() {
    
        viewIsDark = true
        setNeedsStatusBarAppearanceUpdate()
    }
    
    func makeViewLight() {
    
        viewIsDark = false
        setNeedsStatusBarAppearanceUpdate()
    }
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
    
        if viewIsDark {
            return .lightContent 
        } else {
            return .default 
        } 
    }
    
  • 3

    对于目标C,只需在您的应用程序didFinishLaunch方法中添加此行

    UIApplication.sharedApplication.statusBarStyle = UIStatusBarStyleLightContent;
    

相关问题