prefersStatusBarHidden方法未被调用

33

我有一个 UITabViewController -> UINavigationController -> UIViewController,想要隐藏和显示状态栏,但是当我调用 setNeedsStatusBarAppearanceUpdate() 方法时,prefersStatusBarHidden 方法并没有被调用。

func fadeOutStatusBar (notification: NSNotification) {
    statusBarHidden = true
    self.setNeedsStatusBarAppearanceUpdate()
}

func fadeInStatusBar (notification: NSNotification) {
    statusBarHidden = false
    self.setNeedsStatusBarAppearanceUpdate()
}

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

1
这个在操作系统中已经被讨论了很多次。请参考这里 - Jamil
只有被接受的答案与我的相反。 - Md1079
@Md1079,那是因为你的问题不够清晰 - 听起来像是你在问如何在一个视图中完成,所以大多数人给出了只调整一个视图的解决方案,而Nghia Luong则回答了两个都有帮助的选项。 - Natalia
你可能想要查看以下答案:https://dev59.com/lKvka4cB1Zd3GeqP1PMo#52210933 - Claus
9个回答

40

首先,.plist 文件中的 View controller-based status bar appearance 必须设置为 YES

  • 如果您希望整个应用程序中都隐藏状态栏:

对于 Objective-C:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [application setStatusBarHidden:YES];

    return YES;
}

对于Swift:

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

    return true
}
  • 如果您想要在指定视图控制器中隐藏状态栏,在.m文件中实现以下代码:

对于Objective-C:

```objective-c - (BOOL)prefersStatusBarHidden { return YES; } ```
```objective-c - (BOOL)prefersStatusBarHidden { return YES; } ```
- (BOOL)prefersStatusBarHidden {
    return YES;
}

对于Swift编程语言:

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

3
针对 Swift 3 :application.setStatusBarHidden(true, with: .none) 的意思是隐藏状态栏,而 .none 表示状态栏的隐藏动画为无。以及override var prefersStatusBarHidden: Bool { return true } 的意思是重写方法 prefersStatusBarHidden 并返回 true ,从而使状态栏被隐藏。 - neave
2
我忘记了属性列表文件,谢谢! - Kyle Redfearn
您还需要将“状态栏初始隐藏”设置为YES。 - Siempay
statusBarHidden has been renamed to isStatusBarHidden - Jonny

24

找到了解决方法,在info.plist文件中: 查找view controller-status bar appearance并设置为YES


5
如果你能更详细地解释这将实现什么效果,那么你的回答会更有用。是在整个应用程序中隐藏本地状态栏?还是全局性地隐藏状态栏?(请注意,您的答案展示了如何在全局范围内进行操作,而您最初的问题似乎是要求针对“视图”如何进行操作)。这让人感到困惑和不清楚。我认为你应该接受 Nghia 的答案。 - Natalia
是的,它让视图控制器处理状态栏。否则,代理将永远不会被调用。 - Medhi

16

对于 Swift 3,首先确保在您的 Info.plist 文件中将 View controller-based status bar appearance 设置为 YES

screenshot

然后只需将此代码添加到您的视图控制器中:

override var prefersStatusBarHidden: Bool {
    get {
        return true
    }
}

我希望这能帮助未来的人们。


11
当我们嵌套UINavigationController时,通常会设置AppDelegate. Window. RootViewController。一般我们在第一次调用navigationController的childViewControllerForStatusBarHidden函数时创建navigationController,因为默认返回nil,然后再调用navigationController的prefersStatusBarHidden函数。所以我们通过prefersStatusBarHidden函数在viewController中设置的状态栏不会被调用,因此无法生效。
因此我们需要创建一个继承自NavigationController的子类,在这个子类中重写ChildViewControllerForStatusBarHidden函数,以便我们能够正确地显示状态栏。
如果您将UINavigationController用作您的AppDelegate的window.rootViewController,则可能希望扩展UINavigationController以调用其topViewController的prefersStatusBarHidden函数。
class YourNavigationController: UINavigationController {
    override var childForStatusBarHidden: UIViewController? {
        return topViewController
    }
}

刚刚救了我一命,不然我就要撞墙了!谢谢!! - christostsang
我也是。我都快疯了。没有人提到过这个。谢谢@JackySong。 - Houman
我在Swift 5上也是一样。尝试了其他所有方法,最后这个才成功。如果你的应用程序子类化了UINavigationController,请确保在你的ViewController中尝试这个方法,并重写prefersStatusBarHidden - Jake Z

11

也许不是解决 OP 问题的方法,但导致 prefersStatusBarHidden 没有被调用的原因可能还包括:如果您在应用程序委托中使用了第二个窗口(例如用于显示启动画面),并且在显示启动画面后没有隐藏它,则该窗口会获取导致调用这些函数的事件。


谢谢您。您最终是如何解决这个问题的,以便状态栏被显示出来? - toddg
我不记得了,但可能是隐藏我提到的窗口 :-) - TheEye

2

属性prefersStatusBarHidden被调用在当前视图控制器的根视图控制器上。

这意味着如果您的应用程序基于UISplitViewController,您必须在自定义的UISplitViewController类中实现该属性。


1
如果您有其他未隐藏的 window,该方法将不会被调用。只需隐藏其他窗口,它就会按照您的意愿工作。

1

针对Swift 4.2 iOS 12

假设您有一个包含在UINavigationController中的ViewController。创建自己的UINavigationController子类,并在其中包含:

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

请确保 info.plist 设置了基于 View Controller 的状态栏设置


0

您只需要隐藏导航控制器,statusBar也会被隐藏。

尝试这个viewDidLoad示例

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.setNavigationBarHidden(false, animated: false)
}

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