隐藏状态栏Swift 4

22

我试图在我的一个UIViewControllers(Swift 4)中隐藏状态栏。

  • 首先,我在Info.plist中将View controller-based status bar appearance设置为YES

  • 然后在我的控制器中重写了prefersStatusBarHidden属性:


override var prefersStatusBarHidden: Bool {
     return true
}

  • viewDidLoad() 方法中,我添加了 setNeedsStatusBarAppearanceUpdate() 函数以强制读取 prefersStatusBarHidden 属性。

尽管如此,在那个 UIViewController 上我仍然看到状态栏。

请问有人能帮帮我吗?


也许如果您添加一些代码,将有助于提供答案。 - Kalamarico
请查看此链接:https://dev59.com/4FkT5IYBdhLWcg3wPtIv#38876435 - Anbu.Karthik
@Anbu.Karthik,你链接的答案是问题提出者已经完成的。 - Tamás Sengel
我已经尝试了@Anbu.Karthik评论中提到的所有内容。 - Dragisa Dragisic
你是否正在使用 UIPageViewController 或其他视图层次结构? - PGDev
显示剩余3条评论
15个回答

24

您可以通过添加以下代码,隐藏任何或所有的视图控制器中的状态栏:

override var prefersStatusBarHidden: Bool {
     return true
   }

任何包含该代码的视图控制器默认情况下都会隐藏状态栏。

如果您希望动画显示或隐藏状态栏,只需在您的视图控制器上调用setNeedsStatusBarAppearanceUpdate() - 这将强制重读prefersStatusBarHidden,此时您可以返回不同的值。 如果您愿意,您对setNeedsStatusBarAppearanceUpdate()的调用实际上可以位于动画块内,这会使状态栏以平滑的方式隐藏或显示。


我尝试了所有的方法,包括在viewDidLoad()中设置UIApplication.shared.isStatusBarHidden = true,但状态栏仍然存在...我阅读了Swift 4的更改日志,没有关于更改prefersStatusBarHidden的内容。 - Dragisa Dragisic
我在我的Swift 4项目中所做的只是添加override关键字,仅此而已,它就可以工作了。不需要更改Info.plist文件,也不需要调用setNeedsStatusBarAppearanceUpdate()函数。 - ffabri
对我来说可以运行。我没有触碰 plist 文件。只是将上面的代码复制粘贴到 UIViewController 子类中。 - Moondra

8

你可能已经找到了自己的解决方案,但我是这样使它工作的:

override func viewWillAppear(_ animated: Bool) {
    // Sets the status bar to hidden when the view has finished appearing
    let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
    statusBar.isHidden = true
}

override func viewWillDisappear(_ animated: Bool) {
    // Sets the status bar to visible when the view is about to disappear
    let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
    statusBar.isHidden = false
}

4
这是一些风险代码……如果出于某种原因苹果更改子类(他们过去曾经更改过更疯狂的东西),可能会导致崩溃。 - RyanG
如果您使用null运算符,最坏的情况是它会出现。如果让statusBar:UIView = UIApplication.shared.value(forKey:“statusBar”)as?UIView { statusBar.isHidden = false } - Joel Teply

5
如果您正在以模态方式呈现视图控制器,请尝试使用以下代码:
viewController.modalPresentationCapturesStatusBarAppearance = true

太好了!你救了我的命 :) - YannSteph

4

虽然有一些更简洁的实现方式,比如:

UIApplication.shared.isStatusBarHidden = true

但在转换过程中会出现一些奇怪的剪裁动画。虽然更冗长,但我更喜欢@MachTurtle的解决方案:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        if let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as? UIView{
        statusBar.isHidden = true
        }
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(true)
    let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
    statusBar.isHidden = false
}

试一下,对我来说效果很好。


6
这是一些有风险的代码……如果苹果公司出于某种原因更改了子类(他们过去也曾经改过更疯狂的东西),那就会导致崩溃。 - RyanG

4
尝试在Info.plist中将“View controller-based status bar appearance”标志设置为YES。这将强制应用程序在每个视图控制器上调用“prefersStatusBarHidden: Bool”属性。

View controller-based status bar appearance flag


1

正如你所说,你正在使用UINavigationController导航到自定义视图控制器。我想你已经将你的自定义视图控制器设置为UINavigationController的根视图。在这种情况下,在你的自定义视图控制器中覆盖var prefersStatusBarHidden将不起作用,但你需要子类化你的UINavigation Controller并在那里重写属性,如下所示:

class CustomNavigationController: UINavigationController {

    override var prefersStatusBarHidden: Bool {
        return true
    }

}

1
使用以下代码:UIApplication.shared.isStatusBarHidden = true
这是我在iOS11中找到的唯一有效的方法。你可以在didFinishLaunchingWithOptions或你的BaseViewControllerviewWillAppear中编写。 享受吧。

1
我发现我的视图控制器中没有调用prefersStatusBarHidden,因为我使用了自定义容器视图,所以我需要将状态栏隐藏的责任转发给子视图控制器。在容器视图控制器中实现var childForStatusBarHidden: UIViewController? { return childViewController }可以解决这个问题。

1

当您尝试为位于UINavigationStack中的ViewController重载statusbar属性时,您需要创建以下扩展。

extension UINavigationController {
  override open var childForStatusBarStyle: UIViewController? {
    return self.topViewController
  }
}

然后您的重载属性将变得有效。

1
我正在寻找相关内容,对我有用的是:
Swift 5
override var prefersStatusBarHidden: Bool {
  return true
 }

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