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

Posted

技术标签:

【中文标题】如何在 Swift iOS 应用程序中隐藏状态栏?【英文标题】:How do I hide the status bar in a Swift iOS app? 【发布时间】:2014-08-05 21:04:19 【问题描述】:

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

这不起作用:

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

【问题讨论】:

How to hide a status bar in ios?的可能重复 【参考方案1】:

你真的应该在你的视图控制器上实现 prefersStatusBarHidden:

Swift 3 及更高版本

override var prefersStatusBarHidden: Bool 
    return true

【讨论】:

我认为Jay的意图是隐藏完整应用程序的状态栏。这就是为什么他会在应用程序的 didFinishLaunchingWithOptions 中编写隐藏功能。如何隐藏完整应用的状态栏? @Satyam 有好处,在整个应用程序中删除它会很好。有没有办法通过继承来实现这一点?还是通过协议扩展? @DanBeaulieu 我认为通过继承将是一个很好的解决方案。创建一个 UIViewController 子类,其中 bar hidden 设置为 true,然后让您的所有子类都继承自该子类。另一种方法可能是使用Swizzling Swift 3 代码不起作用,请参阅:***.com/a/38902285/129202 这个方法有一个错误:当你想执行一个segue时,你当前viewcontroller的父视图下降了大约20 px【参考方案2】:
    转到 Info.plist 文件 将鼠标悬停在其中一行上,将显示 (+) 和 (-) 按钮。 单击加号按钮添加新键 输入以大写 V 开头,自动第一个选择将是 View controller-based status bar appearance。 将其添加为 KEY。 将值设置为“否” 转到您的 AppDelegate.swift

    在方法内部添加代码

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

完成!运行您的应用,不再有状态栏!

【讨论】:

起初我认为这个解决方案运行良好,但后来我注意到它会导致我需要使用 CG_CONTEXT_SHOW_BACKTRACE 进行调试的错误。回溯到添加“基于视图控制器的状态栏外观” 适用于 iOS 10.1 模拟器。谢谢,@nycdanie。 除了将“基于视图控制器的状态栏外观”设置为NO外,还将“状态栏最初隐藏”设置为“YES”。这样就不需要在视图控制器中添加代码,状态栏就会隐藏在整个应用程序中。 Xcode 8.1、Swift 3.0.1、iOS 10 对 swift 3 Xcode 8 使用 UIApplication.shared.isStatusBarHidden = true @tylerSF 效果很好!您应该将此添加为答案:)【参考方案3】:

斯威夫特 3

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

并致电UIApplication.shared.isStatusBarHidden = true

【讨论】:

如果设置为yes,这是唯一可行的方法。 @farzadshbfn 这不对。正如我所提到和测试的那样,它确实适用于布尔 NO。 自 iOS 13 起已弃用【参考方案4】:

如果您想隐藏和恢复状态栏点击按钮,同时在呈现和关闭滑入式菜单时,弹出窗口 等,那么你可以使用这个方法:-

隐藏状态栏:-

UIApplication.shared.keyWindow?.windowLevel = UIWindowLevelStatusBar

要恢复状态栏:-

UIApplication.shared.keyWindow?.windowLevel = UIWindowLevelNormal 

【讨论】:

这更像是一种黑客行为。我不想干涉这样的窗口......特别是如果已经存在解决方案。我会鼓励开发人员像已经提到的那样覆盖 prefersStatusBarHidden 属性。 如果我们想暂时隐藏并带回状态栏,可以使用此功能。在我的应用程序中,当滑块菜单来自左侧时,我必须隐藏状态栏。当菜单消失时,我们必须带回状态栏,就像在 gmail 的 iOS 应用中一样。所以在这种情况下,我们可以使用它。 这是一个 hack,我不会干预它,但它目前确实有效。就像你们都说的那样。 prefersStatusBarHidden 的问题在于,如果您使用prefersStatusBarHidden 打开/关闭状态栏,使用约束和导航栏绑定到状态栏的视图会以不好的方式移动。目前只有这个答案似乎可以解决这个问题。 完全同意@Jonny,我也不喜欢这个解决方案,但就像他说的那样,覆盖prefersStatusBarHidden 会弄乱你的约束。到目前为止,这是可行的。但是我使用了一个小包装器来避免使用单例,你可以找到它here【参考方案5】:

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

只需将View controller-based status bar appearance 添加到NO

Status bar is initially hidden 作为YES

【讨论】:

这是 2018 年的标准答案 最佳答案!干杯伙伴!【参考方案6】:

iOS 10 / Swift 3.0 更新

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

override var prefersStatusBarHidden: Bool 
    return true

【讨论】:

你知道如何在整个应用程序中设置这个吗,我目前必须在每个视图控制器中输入这个 尝试查找菜单,然后在项目中查找和替换?可能?但是那个带有嵌套 get 的该死的额外支撑......嗯......不知道。好问题! prefersStatusBarHidden 从未被调用过 如果没有set,则不需要get ,只需写return true【参考方案7】:
 override func viewWillAppear(animated: Bool) 
    super.viewWillAppear(true);
    navigationController?.navigationBar.hidden = true // for navigation bar hide
    UIApplication.sharedApplication().statusBarHidden=true; // for status bar hide

【讨论】:

【参考方案8】:

转到您的 Info.plist 并添加两个 Key:

【讨论】:

【参考方案9】:

在 Swift 3.x 中:

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

【讨论】:

这在 iOS 9.0 中已弃用【参考方案10】:

所以这里的问题实际上与 Swift 无关,而与 iOS 7 中状态栏外观的处理方式有关。

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

prefersStatusBarHidden, preferredStatusBarStyle, preferredStatusBarAnimation,

在您的情况下,您只需实现 prefersStatusBarHidden 并返回 true

另一种方法是在应用程序级别控制状态栏的外观。这似乎是你真正想要做的(通过设置application.statusBarHidden)。

为了完成这项工作,您需要打开应用程序的Info.plist 文件并添加密钥UIViewControllerBasedStatusBarAppearance,并为其赋值NO

【讨论】:

我认为你的意思是 return true 为 prefersStatusBarHidden。 NO 属于 ObjC 并且无论如何都是错误的布尔值。 @HenryRootTwo 不在 .plist 文件中。那里我们仍然使用 YES/NO【参考方案11】:

斯威夫特 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(...) 使过渡更平滑。

【讨论】:

【参考方案12】:

其实我自己也想通了。我将添加我的解决方案作为另一种选择。

extension UIViewController 
    func prefersStatusBarHidden() -> Bool 
        return true
    

【讨论】:

保持清洁和模块化的好方法 我无法实现这个。也许是因为现在我使用的是 Swift 1.2。我收到错误消息:“方法 'prefersStatusBarHidden()' 与 Objective-C 选择器 'prefersStatusBarHidden' 与先前声明与相同的 Objective-C 选择器冲突”。我还在开头添加了 override 关键字,但仍然出现相同的错误。 你需要将这个添加到每个视图中吗? 在 Swift 2 中不起作用,显示错误,如上面@Andrej 所述。【参考方案13】:

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

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

override func prefersStatusBarHidden() -> Bool 
     return true

有效,但不提供我可以根据条件进行更改的可编程解决方案。 (statusBarHidden = truestatusBarHidden = false 就像我们之前所做的那样)。

这种疯狂的解决方案:

通过添加到prefersStatusBarHidden() 如下所示,您可以通过编程方式控制状态栏的隐藏和显示,而无需将UIViewControllerBasedStatusBarAppearance 设置添加到您的info.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)

【讨论】:

prefersStatusBarHidden 打电话有意义吗?我猜你的意思是self.setNeedsStatusBarAppearanceUpdate()showStatusBar 之后分配 真的很疯狂,不是吗?这是一个多么可怜的 API,而且已经存在了这么久。这种事情有时会让 iOS 开发非常令人沮丧。 @Womble,是的,它也会变得相当复杂。希望 Swift 3.0 有一个更好的库并支持它,乍一看,它会从 swift 2.3 中改变很多......破坏性的东西。 您可以调用 setNeedsStatusBarAppearanceUpdate 而不是从您的方法中调用 prefersStatusBarHidden 【参考方案14】:

补充一句,在覆盖prefersStatusBarHidden方法或变量时,Info.plist中的View controller-based status bar appearance必须为YES,否则覆盖无效

【讨论】:

【参考方案15】:

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

override var prefersStatusBarHidden: Bool 
    return true

【讨论】:

【参考方案16】:

就我而言,我一直在寻找状态栏来按需隐藏/显示;而不仅仅是在视图加载或消失时。

swift 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()

【讨论】:

【参考方案17】:

对于 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()

【讨论】:

【参考方案18】:

斯威夫特 5: 在主视图控制器或主导航控制器(如果有)中,

    override var preferredStatusBarStyle: UIStatusBarStyle 
        return .lightContent
    

    override var prefersStatusBarHidden: Bool 
        return false
    

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

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

【讨论】:

【参考方案19】:

为 iOS 13 和 Swift 5 更新

如果以上答案都不适合您。检查你的 plist 看看你是否有这个:

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

如果是这样,请务必将其设置为 YES!!!!!

那么下面的代码就可以工作了。

override var prefersStatusBarHidden: Bool 
    return true

【讨论】:

完全正确。其他答案仅适用于“否”,因为我猜你也将“开始隐藏”值设置为“是”。但我们确实想说状态栏的外观是基于控制器的,而不是基于系统的。这样,控制器可以指定prefersStatusBarHidden()...【参考方案20】:

适合我的解决方案;如果你想在加载时隐藏特定视图控制器上的状态栏:

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 属性,因为它是一个存储属性!但是,您可以选择其他名称,然后您的动画就可以工作了。【参考方案21】:

在你的项目General->Deployment Info->Status bar style 选择隐藏状态栏的复选标记 注意:- 它在整个应用程序中隐藏状态栏

【讨论】:

这适用于我(ios 12),而 plist 的答案却没有。【参考方案22】:

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

Project > General

我希望这会有所帮助。

【讨论】:

【参考方案23】:

如果您以模态方式呈现视图控制器,请尝试

viewController.hidesBottomBarWhenPushed = true
viewController.modalPresentationCapturesStatusBarAppearance = true

【讨论】:

【参考方案24】:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
        application.isStatusBarHidden = true
        return true
    

【讨论】:

回答问题时,请说明你的答案,代码sn-p不是正确答案。【参考方案25】:

你可以在你的ViewControllerClassscope使用这个代码

open override var prefersStatusBarHidden: Bool  return true 

【讨论】:

感谢您的回答,您愿意再详细说明一下。他必须在哪里添加代码行,为什么会这样?请参阅How do I write a good answer 部分。【参考方案26】:

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

状态栏样式:--

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

【讨论】:

【参考方案27】:

斯威夫特 4

//MARK:- Show Status Bar
UIApplication.shared.isStatusBarHidden = false

//MARK:- Hide Status Bar
UIApplication.shared.isStatusBarHidden = true

【讨论】:

好的,现在我没有任何 ios 12 我有 11.4,当它更新时我也会修复它,如果你有 teamviewer 我会来修复它在你的系统上 已弃用

以上是关于如何在 Swift iOS 应用程序中隐藏状态栏?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用点击手势(iOS8 / Swift)在 pageViewController 上显示/隐藏状态栏

Swift/iOS 8,当 prefersStatusBarHidden() 设置为 true 时,状态栏不隐藏

隐藏导航栏时隐藏状态栏 - SWIFT iOS8

Swift iOS - 即使我隐藏它,导航栏也不会保持隐藏状态

如何在swift中逐渐隐藏状态栏

Swift如何在IOS中隐藏运营商,时间和电池[重复]