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

217

我希望移除屏幕顶部的状态栏。

以下方法不起作用:

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
}

可能是如何在iOS中隐藏状态栏?的重复问题。 - Jake Chasan
27个回答

477

你真的应该在你的视图控制器(们)中实现prefersStatusBarHidden:

Swift 3及更高版本

override var prefersStatusBarHidden: Bool {
    return true
}

5
我认为Jay的意图是隐藏完整应用程序的状态栏。这就是为什么他会在应用程序的didFinishLaunchingWithOptions中编写隐藏功能的原因。如何隐藏整个应用程序的状态栏? - Satyam
@Satyam有很好的观点,将其从整个应用程序中删除会很不错。是否有通过继承实现此功能的方法?或者通过协议扩展? - Dan Beaulieu
3
@DanBeaulieu 我认为通过继承会是一个很好的解决方案。创建一个UIViewController的子类,其中bar hidden设置为true,然后使所有的子类都继承自该类。另一种方法可以使用Swizzling - crisisGriega
1
Swift 3代码无法运行,请参见:https://dev59.com/kmAf5IYBdhLWcg3w0Ve7#38902285 - Jonny
1
在这种方法中存在一个错误:当您想执行segue时,当前视图控制器的父视图会向下移动约20像素。 - iman kazemayni

104
  1. 前往 Info.plist 文件
  2. 将鼠标悬停在其中一行上,会显示一个 (+) 和 (-) 按钮。
  3. 单击加号按钮以添加新键,请输入以大写字母 V 开头,自动选择第一个选项为 View controller-based status bar appearance。
  4. 将其添加为 KEY。
  5. 将 VALUE 设置为 "NO"
  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上运行良好。 - uplearned.com
1
已在iOS 10.1模拟器上工作。感谢@nycdanie。 - Jerome
8
除了将“View controller-based status bar appearance”设置为NO之外,还需添加“Status bar is initially hidden”并将其设为“YES”。这样,您无需在视图控制器中添加代码,整个应用程序中的状态栏都将被隐藏。Xcode 8.1,Swift 3.0.1,iOS 10。 - tylerSF
1
在 Swift 3 Xcode 8 中使用 UIApplication.shared.isStatusBarHidden = true。 - oOEric
1
@tylerSF 好棒!你应该把这个作为一个答案添加 :) - Pétur Ingi Egilsson

77

Swift 3

Info.plist中将View controller-based status bar appearance设置为NO

并调用UIApplication.shared.isStatusBarHidden = true


1
如果设置为是,这是唯一的工作方式。 - farzadshbfn
@farzadshbfn,那不对。正如我所提到并测试过的,它可以使用布尔值NO。 - Codetard
1
自iOS 13起,此功能已被弃用。 - Xys

44
如果您想通过按钮点击来隐藏和恢复状态栏,在呈现和解除幻灯片菜单、弹出窗口等操作时,可以使用以下方法:
隐藏状态栏:
UIApplication.shared.keyWindow?.windowLevel = UIWindowLevelStatusBar

恢复状态栏的方法:

UIApplication.shared.keyWindow?.windowLevel = UIWindowLevelNormal 

这更像是一种hack。我不想像这样干涉窗口...特别是如果已经存在解决方案的情况下。我鼓励开发人员覆盖prefersStatusBarHidden属性,就像已经提到的那样。 - Stephen Paul
2
这可以用来暂时隐藏和恢复状态栏。在我的应用程序中,当滑动菜单从左侧出现时,我必须隐藏状态栏。当菜单消失时,我们必须恢复状态栏,就像 Gmail 的 iOS 应用程序一样。因此,在这些情况下,我们可以使用此功能。 - Vincent Joy
3
这确实是个技巧,我不会干涉它,但目前它确实起作用。有点像你们所说的。使用“prefersStatusBarHidden”存在问题,因为使用约束绑定到状态栏的视图以及导航栏,如果使用“prefersStatusBarHidden”切换状态栏的显示/隐藏,这些视图会出现不良的移动。目前只有这个答案似乎可以解决这个问题。 - Jonny
完全同意@Jonny的观点,我也不喜欢这个解决方案,但就像他所说的,覆盖prefersStatusBarHidden会破坏你的约束。到目前为止,这个方法可以解决问题。然而,我使用了一个小包装器来避免使用单例,你可以在这里找到它。 - rgkobashi

43

如果您更喜欢视觉方式而非编码方法,请使用以下方法:

在您的 info.plist 中,

enter image description here 只需将 View controller-based status bar appearance 设置为 NO

并将 Status bar is initially hidden 设为 YES


这是2018年的规范答案。 - ChrisH
3
最佳答案!干杯,伙计! - Pressing_Keys_24_7

28

iOS 10 / Swift 3.0 更新

不再是一个函数,现在是一个属性...

override var prefersStatusBarHidden: Bool {
    return true
}

你知道如何在整个应用程序中设置这个吗?我目前必须在每个视图控制器中输入它。 - William T.
尝试使用“查找”菜单,然后在项目中进行“查找和替换”?也许?但是那个嵌套的get多了一个括号... 嗯...不知道。好问题! - atlwx
prefersStatusBarHidden从未被调用过。 - Bagusflyer
6
如果没有set,你就不需要get{},只需写return true即可。 - Daniel

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
}

19

前往您的Info.plist文件并添加两个键:

前往您的Info.plist文件并添加两个键:


16

在Swift 3.x中:

override func viewWillAppear(_ animated: Bool) {
    UIApplication.shared.isStatusBarHidden = true
}

在iOS 9.0中,此功能已被弃用。 - Georgios

13

Swift 5+

在我的情况下,我需要根据一些条件更新状态栏的隐藏状态。

因此,我创建了一个基础控制器BaseViewController,其中包含新属性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(...)来使过渡更加顺畅。

输入图像描述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接