如何在带有导航栏的模式视图中更改 iOS 7 中的 UIStatusBarStyle?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18999019/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:40:16  来源:igfitidea点击:

How to change UIStatusBarStyle in iOS 7 in modal views with navigation bar?

iosios7modalviewcontrollerstatusbar

提问by FrankZp

The iOS 7 Transition Guidegive a good hint how to change the UIStatusBarStyledynamically in a UIViewControllerusing

iOS的7过渡指南提供一个很好的提示如何改变UIStatusBarStyle在动态UIViewController使用

- (UIStatusBarStyle)preferredStatusBarStyle {
     return UIStatusBarStyleDefault;
}

together with [self setNeedsStatusBarAppearanceUpdate];

和...一起 [self setNeedsStatusBarAppearanceUpdate];

This works fine in a single view application. However, I'm now trying to change the UIStatusBarStylein a modal view to UIStatusBarStyleLightContent. There is a MainViewControllerwhich segues to the ModalViewController, which itself is embedded in a NavigationController. The ModalViewControllerhas set its delegate to the MainViewController.

这在单视图应用程序中工作正常。但是,我现在正在尝试将UIStatusBarStyle模态视图中的更改为UIStatusBarStyleLightContent. 有一个MainViewControllerwhich segues 到ModalViewController,它本身嵌入在 a 中NavigationController。在ModalViewController已设置其委托的MainViewController

I tried to call [self setNeedsStatusBarAppearanceUpdate];in the ModalViewControllertogether with the following method in that class without effect:

我试图在该类中与以下方法一起调用[self setNeedsStatusBarAppearanceUpdate];,但ModalViewController没有效果:

// In ModalViewController.m
- (UIStatusBarStyle)preferredStatusBarStyle {
     return UIStatusBarStyleLightContent;
}

I also tried to call [self setNeedsStatusBarAppearanceUpdate];in MainViewControlleron prepareForSegue: sender:method with conditions in - (UIStatusBarStyle)preferredStatusBarStyle {}to return UIStatusBarStyleLightContentwhen the modal view is presented - but that has no effects, too.

我还尝试[self setNeedsStatusBarAppearanceUpdate];在呈现模态视图时调用带有条件的MainViewControlleronprepareForSegue: sender:方法- (UIStatusBarStyle)preferredStatusBarStyle {}以返回UIStatusBarStyleLightContent- 但这也没有效果。

How can I change the UIStatusBarStyle in the modal view?

如何在模态视图中更改 UIStatusBarStyle?

EDIT:Post updated: I need to mention that the ModalViewControlleris embedded in a NavigationControllerwith a NavigationBar. With NavigationBarset to hidden to above call of [self setNeedsStatusBarAppearanceUpdate];in ModalViewControllerworks fine. But not when the Bar is visible.

编辑:更新后:我需要提到的ModalViewController是嵌入在NavigationController带有NavigationBar. 随着NavigationBar设置为隐藏的上述通话[self setNeedsStatusBarAppearanceUpdate];ModalViewController工作正常。但不是当 Bar 可见时。

回答by jaetzold

You need a ViewController that's showing in Fullscreen to return the appropriate status bar infos. In your case: The NavigationController which contains ModalViewController needs to implement preferredStatusBarStyleand return UIStatusBarStyleLightContent.

您需要一个全屏显示的 ViewController 以返回适当的状态栏信息。在您的情况下:包含 ModalViewController 的 NavigationController 需要实现preferredStatusBarStyle并返回UIStatusBarStyleLightContent

A call to setNeedsStatusBarAppearanceUpdateis only necessary if the values a view controller returns actually change. When the view controller is first presented they are queried anyway.

setNeedsStatusBarAppearanceUpdate仅当视图控制器返回的值实际发生变化时才需要调用。当第一次呈现视图控制器时,无论如何都会查询它们。

回答by Puttin

We should notice that non-fullscreen modalVC CANuse modalPresentationCapturesStatusBarAppearanceto control the statusBar style.

我们应该注意到,是非全屏modalVC CAN使用modalPresentationCapturesStatusBarAppearance控制状态栏的风格。

Anyone who wanna know more about Status Bar control should not ignore the UIViewController Managing the Status Bar.

任何想了解更多有关状态栏控件的人都不应忽略UIViewController 管理状态栏

Update at 2015-11-06:

2015-11-06 更新:

And make sure you have set UIViewControllerBasedStatusBarAppearancedescribed in iOS Keys

并确保您已UIViewControllerBasedStatusBarAppearanceiOS Keys 中进行了设置

Update at 2018.04.09:

2018.04.09 更新:

I noticed that viewController in a navController may not get call prefersStatusBarHiddenwith iOS 10.0 - 10.2. Custom your navigationController to ensure that

我注意到在prefersStatusBarHiddeniOS 10.0 - 10.2 中,navController 中的 viewController 可能无法调用。自定义您的 navigationController 以确保

@implementation YourCustomNavController
//for iOS 10.0 - iOS 10.2
- (BOOL)prefersStatusBarHidden {
    UIViewController *childVC = [self childViewControllerForStatusBarHidden];
    if (childVC) {
        return [childVC prefersStatusBarHidden];
    }
    return [super prefersStatusBarHidden];
}
@end

And anyone who want to go deeper inside can dig into UIKit +[UIViewController _currentStatusBarStyleViewController]using Hopper or IDA Pro. It may helps you solve these kinds of bugs.

任何想要深入了解的人都可以+[UIViewController _currentStatusBarStyleViewController]使用 Hopper 或 IDA Pro深入研究 UIKit 。它可以帮助您解决这些类型的错误。

回答by Juddster

The key to making this work is that only the fullscreen view controller get's to dictate the style of the status bar.

完成这项工作的关键是只有全屏视图控制器才能决定状态栏的样式。

If you are using a navigation controller and want to control the status bar on a per view controller basis, you'll want to subclass UINavigationController and implement preferredStatusBarStyle such that it returns the topViewController's preference.

如果您正在使用导航控制器并希望在每个视图控制器的基础上控制状态栏,您将需要继承 UINavigationController 并实现 preferredStatusBarStyle 以便它返回 topViewController 的首选项。

Make sure you change the class reference in your storyboard scene fromUINavigationController to your subclass (e.g. MyNavigationController in the example below).

确保将故事板场景中的类引用从UINavigationController 更改为您的子类(例如下面示例中的MyNavigationController)。

(The following works for me. If your app is TabBar based, you'll want to do something similar by subclassing the UITabBarController but I haven't tried that out).

(以下对我有用。如果您的应用程序基于 TabBar,您将希望通过继承 UITabBarController 来做类似的事情,但我还没有尝试过)。

@interface MyNavigationController : UINavigationController

@end

@implementation MyNavigationController

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return self.topViewController.preferredStatusBarStyle;
}

@end

回答by Alex Wally

To change the status bar of the UINavigationController embedding your ViewController without subclassing UINavigationController, use this:

要更改嵌入您的 ViewController 的 UINavigationController 的状态栏而不继承 UINavigationController,请使用以下命令:

navigationController?.navigationBar.barStyle = .Black // to make the status bar text white

.Black will make the text white (status bar and the view's title), while .Default has a black title and status bar.

.Black 将使文本变为白色(状态栏和视图的标题),而 .Default 具有黑色标题和状态栏。

回答by Graham Perks

I had a side menu/reveal controller (SWRevealController) which turns out to always be the root controller for status bar queries. Overriding childViewControllerForStatusBarStylelet me re-route the query to the front most controller.

我有一个侧面菜单/显示控制器(SWRevealController),它始终是状态栏查询的根控制器。覆盖childViewControllerForStatusBarStyle让我将查询重新路由到最前面的控制器。

/**
 This view is always considered the topmost for status bar color queries.
 Pass the query along to what we're showing in front.
 */
- (UIViewController *)childViewControllerForStatusBarStyle
{
    UIViewController *front = self.frontViewController;
    if ([front isKindOfClass:[UINavigationController class]])
        return ((UINavigationController*)front).topViewController;
    else
        return front;
}

回答by samthui7

This works for me:

这对我有用:

  1. Set View controller-based status bar appearanceto NO
  2. Set Status bar style to UIStatusBarStyleLightContent(just copy that value)
  3. In appDelegate use [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
  1. 设置View controller-based status bar appearanceNO
  2. 将状态栏样式设置为UIStatusBarStyleLightContent(只需复制该值)
  3. 在 appDelegate 中使用 [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

Hope it helps (ref: ios7 status bar changing back to black on modal views?)

希望它有所帮助(参考:ios7 状态栏在模态视图上变回黑色?

回答by William Jockusch

It seems like the app goes off the statusBarStyle of the topmost viewController. So if you add another viewController on top of your current one, it now gets its cues from the new viewController.

该应用程序似乎脱离了最顶层 viewController 的 statusBarStyle。因此,如果您在当前视图控制器之上添加另一个视图控制器,它现在会从新的视图控制器获取提示。

回答by devClown

Just look up if your app's rootViewController need to override -(UIStatusBarStyle)preferredStatusBarStyle method

只需查看您的应用程序的rootViewController 是否需要覆盖 -(UIStatusBarStyle)preferredStatusBarStyle 方法

回答by bainfu

All of the above work. However sometimes I find it really a pain in the bottom to go and change every instance in the Storyboard etc... So here's something that works for me that also involves subclassing.

以上所有工作。然而,有时我发现去改变故事板等中的每个实例真的很痛苦......所以这里有一些对我有用的东西也涉及子类化。

First create the subclass:

首先创建子类:

@interface HHNavLightColorBarController : UINavigationController

@end

@implementation HHNavLightColorBarController

- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleLightContent;
}
@end

Then using the magic of Objective-C and a little bit of the <objc/runtime.h>

然后使用 Objective-C 的魔力和一点点 <objc/runtime.h>

When you have a reference of the view controller and your presenting it:

当您有视图控制器的参考并展示它时:

UINavigationController *navVC = ...; // Init in your usual way
object_setClass(navVC, [HHNavLightColorBarController class]);
[self presentViewController:nav animated:YES completion:^{
    NSLog(@"Launch Modal View Controller");
}];

Sometimes it seems a bit less intrusive. You could probably even create a category that checks to see if your kindOfClass is a navigation controller and auto do it for you. Anyways, the answer is above by jaetzold, I just found this to be handy.

有时它似乎不那么具有侵入性。您甚至可以创建一个类别来检查您的 kindOfClass 是否为导航控制器并自动为您执行此操作。无论如何,答案在 jaetzold 上面,我只是觉得这很方便。