如何在Swift iOS应用中隐藏状态栏?


201

我想删除屏幕顶部的状态栏。

这不起作用:

func application
(application: UIApplication,
didFinishLaunchingWithOptions launchOptions: NSDictionary?)
-> Bool
{
        application.statusBarHidden = true
        return true
}

我也尝试过:

func application
(application: UIApplication,
didFinishLaunchingWithOptions launchOptions: NSDictionary?)
-> Bool
{
    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

    var controller = UIViewController()
    application.statusBarHidden = true
    controller.setNeedsStatusBarAppearanceUpdate()

    var view = UIView(frame: CGRectMake(0, 0, 320, 568))
    view.backgroundColor = UIColor.redColor()
    controller.view = view

    var label = UILabel(frame: CGRectMake(0, 0, 200, 21))
    label.center = CGPointMake(160, 284)
    label.textAlignment = NSTextAlignment.Center
    label.text = "Hello World"
    controller.view.addSubview(label)

    self.window!.rootViewController = controller
    self.window!.makeKeyAndVisible()
    return true
}

Answers:


449

您确实应该在视图控制器上实现preferredsStatusBarHidden:

Swift 3及更高版本

override var prefersStatusBarHidden: Bool {
    return true
}

4
我认为Jay的意图是隐藏完整应用程序的状态栏。这就是为什么他会在应用程序的didFinishLaunchingWithOptions中编写隐藏功能的原因。如何隐藏完整应用程序的状态栏?
萨蒂扬2014年

@Satyam有一个好处,最好在整个应用程序中删除它。有没有一种方法可以通过继承来实现呢?还是通过协议扩展?
Dan Beaulieu

3
@DanBeaulieu我认为通过继承将是一个很好的解决方案。创建一个UIViewController子类,其中bar hidden设置为true,然后使所有子类都继承自该子类。另一种方法可能是使用Swizzling –crisisGriega
2016年

1
Swift 3代码无法正常运行,请参阅:stackoverflow.com/a/38902285/129202
Jonny

1
这种方法有一个缺点:当您要执行segue时,当前viewcontroller的父视图会下降约20 px
iman kazemayni

99
  1. 转到Info.plist文件
  2. 将鼠标悬停在其中一行上,然后将显示(+)和(-)按钮。
  3. 单击加号按钮以添加新的密钥,以大写字母V开头,并且自动选择的第一个选项是基于视图控制器的状态栏外观。
  4. 将其添加为密钥。
  5. 将值设置为“否”
  6. 转到您的AppDelegate.swift
  7. 在方法内部添加代码

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject:AnyObject]?) -> Bool {
        application.statusBarHidden = true
        return true
    }

完成!运行您的应用程序,没有更多的状态栏!


1
起初,我认为此解决方案可以正常工作,但是后来我注意到它会导致我需要使用CG_CONTEXT_SHOW_BACKTRACE进行调试的错误。回溯到添加“基于视图控制器的状态栏外观”的问题
Sean

在IOS 9 2.2中对我来说工作正常
uplearnedu.com 2016年

1
适用于iOS 10.1模拟器。谢谢,@ nycdanie。
杰罗姆(Jerome)

7
除了将“基于View Controller的状态栏外观”设置为“否”外,还将“状态栏最初处于隐藏状态”设置为“是”。然后,您无需在视图控制器中添加代码,状态栏将在整个应用程序中隐藏。Xcode 8.1,Swift 3.0.1,iOS 10
tylerSF

1
@tylerSF很棒!你应该将其添加为一个答案:)
PéturIngi Egilsson

72

迅捷3

Info.plist设置View controller-based status bar appearanceNO

并致电 UIApplication.shared.isStatusBarHidden = true


1
如果将其设置为“是”,则它将是唯一起作用的方法。
farzadshbfn

@farzadshbfn那是不对的。如我所提到和测试的,它确实适用于布尔型NO。
Codetard '17年

43

如果要在按钮水龙头上隐藏和恢复状态栏,而在显示和关闭幻灯片菜单弹出窗口等时,则可以使用以下方法:

隐藏状态栏:-

UIApplication.shared.keyWindow?.windowLevel = UIWindowLevelStatusBar

恢复状态栏:-

UIApplication.shared.keyWindow?.windowLevel = UIWindowLevelNormal 

这更像是一个hack。我不想干涉这样的窗口……特别是如果已经存在解决方案的话。我鼓励开发人员prefersStatusBarHidden像已经提到的那样重写该属性。
斯蒂芬·保罗

2
如果我们想暂时隐藏并重新显示状态栏,可以使用此按钮。.在我的应用中,当滑块菜单来自左侧时,我必须隐藏状态栏。并且当菜单消失时,我们必须调出状态栏,例如在gmail的iOS应用中。.因此,在这种情况下,我们可以使用此功能。
文森特·乔伊

3
这是一个黑客,我不会被扎,但它确实工作的时刻。有点像你们都说。问题prefersStatusBarHidden在于,如果使用切换开/关状态栏,则使用约束与状态栏相关联的视图以及导航栏的移动方式将很差prefersStatusBarHidden 。目前,只有这个答案似乎可以解决此问题。
Jonny

完全同意@Jonny的观点,我也不喜欢这种解决方案,但就像他说的那样,覆盖prefersStatusBarHidden将使您的约束变得混乱。到目前为止,这已经完成了工作。但是,我使用小型包装程序以避免使用单例,您可以在这里
rgkobashi

34

如果您更喜欢视觉方式而不是编码方式,请使用以下方法: info.plist

在此处输入图片说明 只需添加View controller-based status bar appearanceNO

Status bar is initially hidden作为YES


这是2018
ChrisH

28
 override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(true);
    navigationController?.navigationBar.hidden = true // for navigation bar hide
    UIApplication.sharedApplication().statusBarHidden=true; // for status bar hide
}

28

iOS 10 / Swift 3.0更新

不再是功能,现在是属性...

override var prefersStatusBarHidden: Bool {
    return true
}

您知道如何在整个应用程序中进行设置吗,我目前必须将其输入到每个viewController中
William T.

尝试查找菜单,然后在项目中查找和替换?也许?但是,用嵌套的get会带来额外的支撑...嗯.... dunno。好问题!
atlwx

preferredsStatusBarHidden从未被称为
Bagusflyer

6
get { }如果您没有,则不需要set,只需写下即可return true
丹尼尔(Daniel)



12

因此,这里的问题实际上与Swift无关,而只是从iOS 7开始如何处理状态栏外观。

默认情况下,视图控制器在屏幕上时分别控制状态栏的外观。如果要使用这种控制状态栏的方法,则可以为想要修改其外观的任何视图控制器覆盖以下方法:

prefersStatusBarHiddenpreferredStatusBarStylepreferredStatusBarAnimation

就您而言,您只需实现prefersStatusBarHidden并返回true

另一种方法是在应用程序级别上控制状态栏的外观。这似乎是您实际上要尝试执行的操作(通过设置application.statusBarHidden)。

为了使这项工作有效,您需要打开应用程序的Info.plist文件并添加密钥UIViewControllerBasedStatusBarAppearance,并将其值设置为NO


1
我认为您的意思是对preferredsStatusBarHidden 返回trueNO属于ObjC,无论如何都是错误的布尔值。
HenryRootTwo14年

@HenryRootTwo不在.plist文件中。在那里,我们仍然使用“是/否”
Alex Salom

8

我实际上是自己想出来的。我将添加解决方案作为另一种选择。

extension UIViewController {
    func prefersStatusBarHidden() -> Bool {
        return true
    }
}

保持物品整洁和模块化的好方法
Roger Fernandez Guri 2014年

2
我无法实现。也许是因为现在我使用Swift 1.2。我收到错误消息:“带有Objective-C选择器'prefersStatusBarHidden'的方法'prefersStatusBarHidden()'与具有相同Objective-C选择器的先前声明发生冲突”。我还在开始时添加了override关键字,但仍然遇到相同的错误。
Andrej 2015年

您是否需要将此添加到每个视图?
肖恩

在Swift 2中不起作用,显示错误,如上面@Andrej所述。
Nagendra Rao 2016年

4

好的,这对我来说是个问题,因为iOS 9不支持人们在此处提到的上述任何方法,例如UIApplication.sharedApplication().statusBarHidden = true 或。

UIApplication.sharedApplication().setStatusBarHidden(true, withAnimation: UIStatusBarAnimation.None)

override func prefersStatusBarHidden() -> Bool {
     return true
}

可以,但是无法提供我可以根据条件更改的可编程解决方案。(statusBarHidden = truestatusBarHidden = false我们之前所做的一样)。

解决这种疯狂的方法:

通过添加prefersStatusBarHidden()如下所示,您可以以编程方式控制状态栏的隐藏和显示,而无需UIViewControllerBasedStatusBarAppearanceinfo.plist中添加设置:

var showStatusBar = true

override func prefersStatusBarHidden() -> Bool {
     if showStatusBar {
         return false
     }
     return true
}

private func showStatusBar(enabled: Bool) {
    showStatusBar = enabled
    prefersStatusBarHidden()
}

然后在整个代码中像这样使用它:

//Hide Status Bar
showStatusBar(false)

要么

//Show Status Bar
showStatusBar(true)

1
是否prefersStatusBarHidden调用任何意义?我想你是指分配self.setNeedsStatusBarAppearanceUpdate()showStatusBar
Leo

真的是疯狂,不是吗?这是一个多么可怜的API,并且已经存在了很长时间。这种事情有时会使iOS开发令人沮丧。
Womble

@Womble,是的,它也可能变得非常复杂。希望Swift 3.0拥有更好的库并支持它,因为乍一看,它将彻底改变Swift 2.3 ...的功能。
CodeOverRide

您可以调用setNeedsStatusBarAppearanceUpdate
Oscar

4

只是要添加,当覆盖prefersStatusBarHidden方法或变量时,View controller-based status bar appearanceInfo.plist中的in必须为YES,否则覆盖无效。


4

在Swift 4.2中,它现在是一个属性。

override var prefersStatusBarHidden: Bool {
    return true
}

3

就我而言,我正在寻找状态栏以根据需要隐藏/显示;而不是仅在视图加载或消失时。

迅速3.x

//show status bar initially
var showStatusBar = true

//set the parameters
override var prefersStatusBarHidden: Bool {

    if showStatusBar == true {

        //does not prefer status bar hidden
        print("does not prefer status bar hidden")
        return false

    } else {

        //does prefer status bar hidden
        print("does prefer status bar hidden")
    return true

    }
}

//ex: hide status bar and call parameter function again whenever you want
        showStatusBar = false
        setNeedsStatusBarAppearanceUpdate()

3

Swift 5:在主视图控制器或主导航控制器(如果有)中,

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }

    override var prefersStatusBarHidden: Bool {
        return false
    }

并且plist中的“基于视图控制器的状态栏外观”必须为YES,否则将不会调用上述代码。

如果要在启动应用程序时隐藏状态栏,则plist中的“状态栏最初处于隐藏状态”必须为YES。当屏幕顶部显示额外的蓝色条时,这可以防止启动图像失真。


2

对我有用的解决方案;如果要在加载时隐藏特定视图控制器上的状态栏,请执行以下操作:

import UIKit

class ViewController: UIViewController {

private var hideStatusBar: Bool = false

override var prefersStatusBarHidden: Bool {
    return hideStatusBar
}

override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
    return UIStatusBarAnimation.slide
}

override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundcolor = .white
    hideStatusBar = true

    UIView.animate(withDuration: 0.3) {
        self.setNeedsStatusBarAppearanceUpdate()
    }
}

注意:如果在info.plist中将键“ 基于视图控制器的状态栏外观 ”设置为“ NO ”,则以上代码无效。您应该将密钥设置为“ YES ”或其从info.plist中 删除


您不能覆盖hideStatusBar属性,因为它是存储属性!不过,您可以选择其他名称,动画就可以使用。
XcodeNOOB

2

在项目的“常规”->“部署信息”->“状态栏”样式中,选择“隐藏状态栏”的复选标记注意:-它会在整个应用程序中隐藏状态栏


1
这对我有效(iOS 12),而plist答案不起作用。
threeve

2

对于Swift 4+,请尝试以下代码(在Swift 4.0、4.1-IOS 10、11上测试):

override var prefersStatusBarHidden: Bool { return true }

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    // call this func to force preferredStatusBarStyle to be read again.
    setNeedsStatusBarAppearanceUpdate()
}

2

迅捷5+

就我而言,我需要根据某些条件更新隐藏的状态栏。

因此,我创建了一个BaseViewController包含new属性的基本控件hideStatusBar

其他视图控制器是此基本控制器的子类。最后,当我想更新状态栏行为时,只需更改此hideStatusBar值。

class BaseViewController: UIViewController {

    var hideStatusBar: Bool = false {
        didSet {
            setNeedsStatusBarAppearanceUpdate()
        }
    }

    override var prefersStatusBarHidden: Bool {
           return hideStatusBar
    }
}

如何使用

final class ViewController: BaseViewController, UIScrollViewDelegate {
    let scrollView = UIScrollView()

    ...

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        UIView.animate(withDuration: 0.3) {
            if scrollView.contentOffset.y > 100 {
                self.hideStatusBar = true
            } else {
                self.hideStatusBar = false
            }
        }
    }
}

演示版

这是一个演示,我正在UIView.animate(...)使过渡更平滑。

在此处输入图片说明


1

我使用的Xcode 8.1(8B62)的部署目标设置为10.1,我对上面提到的替代选项不太满意。但是,检查部署信息中的“隐藏状态栏”选项对我来说有用。

项目>常规

我希望这有帮助。


1

如果您以模态显示视图控制器,请尝试

viewController.hidesBottomBarWhenPushed = true
viewController.modalPresentationCapturesStatusBarAppearance = true

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

4
回答问题时,请解释您的答案,代码段不是正确的答案。
LazerBanana

0

您可以在自己的代码中使用此代码 ViewController Class scope

open override var prefersStatusBarHidden: Bool { return true }

谢谢您的回答,您是否愿意详细说明。他到底在哪里添加代码行,为什么行得通?请参阅 如何写一个好的答案部分。
9953-div-37年

0

在您的项目->常规->部署信息中

状态栏样式:-

刚刚标记为“隐藏状态栏”(iOS 10)



0

已针对iOS 13和Swift 5更新

如果以上答案都不对您有用。检查您的plist以查看是否具有以下功能:

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

如果是这样,请确保将其设置为是!!!!

然后,以下代码将起作用。

override var prefersStatusBarHidden: Bool {
    return true
}
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.