iOS 7状态栏回到iOS 6默认样式的iPhone应用程序?

在iOS 7中,UIStatusBar被设计成这样,它与视图合并:

GUI designed by Tina tavvar (GUI由蒂娜Tavč基于“增大化现实”技术设计)

  • 这很酷,但是当你的视图顶部有一些东西时,它会在某种程度上搅乱你的视图,它会与状态栏重叠。

  • 是否有一个简单的解决方案(比如在info.plist中设置一个属性)可以改变它的工作方式(不重叠)回到iOS6中?

  • 我知道一个更直接的解决方案是为每个单个视图控制器设置self.view.center.x + 20个点,但改变它们会把其他维度搞砸(拥有不同的self.view.center.x会导致自定义segue的问题等),突然它变成了一项最好避免的乏味工作。

  • 如果有人能为我提供一个简单的解决方案,我将非常高兴。

附注:我知道我可以隐藏状态栏

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];

didFinishLaunchingWithOptions方法中,但这是一种变通方法,一种避免问题的快捷方式,所以我不认为这是一个真正的解决方案。

184099 次浏览

你可以一起隐藏状态栏。所以你的应用会是全屏的。我想这是你能得到的最好的了。

UIStatusBarStyleNone或在目标设置中设置。

2013年9月19日更新:

<子>固定缩放bug添加 self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height); < / sub > < / p >

修正了NSNotificationCenter语句中的错别字

< br >

2013年9月12日更新:

UIViewControllerBasedStatusBarAppearance修正为NO

增加了一个解决方案的应用程序与屏幕旋转

增加了一个改变状态栏背景颜色的方法。

< br >

显然,没有办法将iOS7的状态栏恢复到iOS6的工作状态。

然而,我们总是可以写一些代码,把状态栏变成像ios6一样,这是我能想到的最短的方法:

  1. info.plist中将UIViewControllerBasedStatusBarAppearance设置为NO(为了选择不让视图控制器调整状态栏样式,以便我们可以使用UIApplicationstatusBarStyle方法设置状态栏样式)。

  2. 在AppDelegate的application:didFinishLaunchingWithOptions中,调用

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
    [application setStatusBarStyle:UIStatusBarStyleLightContent];
    self.window.clipsToBounds =YES;
    self.window.frame =  CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height-20);
    
    
    //Added on 19th Sep 2013
    self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);
    }
    return YES;
    


in order to:

  1. Check if it's iOS 7.

  2. Set status bar's content to be white, as opposed to UIStatusBarStyleDefault.

  3. Avoid subviews whose frames extend beyond the visible bounds from showing up (for views animating into the main view from top).

  4. Create the illusion that the status bar takes up space like how it is in iOS 6 by shifting and resizing the app's window frame.


For apps with screen rotation,

use NSNotificationCenter to detect orientation changes by adding

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidChangeStatusBarOrientation:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];

if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)中创建一个新方法:

- (void)applicationDidChangeStatusBarOrientation:(NSNotification *)notification
{
int a = [[notification.userInfo objectForKey: UIApplicationStatusBarOrientationUserInfoKey] intValue];
int w = [[UIScreen mainScreen] bounds].size.width;
int h = [[UIScreen mainScreen] bounds].size.height;
switch(a){
case 4:
self.window.frame =  CGRectMake(0,20,w,h);
break;
case 3:
self.window.frame =  CGRectMake(-20,0,w-20,h+20);
break;
case 2:
self.window.frame =  CGRectMake(0,-20,w,h);
break;
case 1:
self.window.frame =  CGRectMake(20,0,w-20,h+20);
}
}

因此,当方向改变时,它将触发一个switch语句来检测应用程序的屏幕方向(纵向,倒置,横向左,或横向右),并分别改变应用程序的窗口框架,以创建iOS 6状态栏错觉。

< br >

更改状态栏的背景颜色:

添加

 @property (retain, nonatomic) UIWindow *background;

AppDelegate.h中使background成为类中的一个属性,并防止ARC释放它。(如果你不使用ARC,你不必这样做。)

之后,你只需要在if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)中创建UIWindow:

background = [[UIWindow alloc] initWithFrame: CGRectMake(0, 0, self.window.frame.size.width, 20)];
background.backgroundColor =[UIColor redColor];
[background setHidden:NO];

别忘了在@implementation AppDelegate之后@synthesize background; !

如果你不希望你的视图控制器被状态栏(和导航栏)重叠,取消勾选界面构建器中的“在顶部栏下扩展边缘”框。

Uncheck the Extend Edges Under Top Bars

Interface Builder中有一个选项,调用iOS 6/7 Delta属性,旨在解决偏移问题。

在Stack Overflow问题界面生成器:什么是UIView的布局iOS 6/7 delta ?< / >中看看它。

这是从我写的一篇博客文章中交叉发布的,但这里是iOS 7中关于状态栏,导航栏和容器视图控制器的完整概述:

  1. 没有办法保持ios6风格的状态栏布局。在iOS 7中,状态栏将始终与你的应用程序重叠

  2. 不要混淆状态栏外观和状态栏布局。外观(浅色或默认)不会影响状态栏的布局(帧/高度/重叠)。同样需要注意的是,系统状态栏不再有任何背景颜色。当API引用UIStatusBarStyleLightContent时,它们指的是清晰背景上的白色文本。UIStatusBarStyleDefault是透明背景上的黑色文本。

  3. 状态栏的外观被控制在两个相互排斥的基础路径之一:你可以用传统的方式通过编程来设置它们,或者UIKit会根据UIViewController的一些新属性来为你更新外观。默认情况下,后一个选项是开启的。检查你的应用程序的plist值“基于视图控制器的状态栏外观”,看看你正在使用哪个。如果你设置这个值为YES,你的应用程序中的每一个顶级视图控制器(除了一个标准的UIKit容器视图控制器)都需要重写preferredStatusBarStyle,返回默认的或轻的样式。如果你将plist值编辑为NO,那么你可以使用熟悉的UIApplication方法来管理状态栏的外观。

  4. UINavigationController将其UINavigationBar的高度更改为44点或64点,这取决于一组相当奇怪且未记录的约束。如果UINavigationController检测到它的视图框架的顶部与它的UIWindow的顶部在视觉上是连续的,那么它就用64点的高度绘制它的导航条。如果它的视图顶部与UIWindow的顶部不相邻(即使只差一个点),那么它以“传统”的方式绘制它的导航条,高度为44点。这个逻辑是由UINavigationController执行的,即使它在你的应用程序的视图控制器层次结构中有几个子控制器。没有办法阻止这种行为。

  5. 如果你提供了一个只有44点(88像素)高的自定义导航栏背景图像,并且UINavigationController的视图边界与UIWindow的边界相匹配(如#4所述),UINavigationController将在帧(0,20,320,44)中绘制你的图像,在你的自定义图像上方留下20点不透明的黑色空间。这可能会使您误以为自己是一个绕过规则1的聪明开发人员,但您错了。导航条仍然有64点高。将UINavigationController嵌入到幻灯片显示样式的视图层次结构中,这一点就非常清楚了。

  6. 注意UIViewController的edgesForExtendedLayout属性。调整edgesForExtendedLayout在大多数情况下没有任何作用。UIKit使用这个属性的唯一方式是如果你添加一个视图控制器到一个UINavigationController,那么UINavigationController使用edgesForExtendedLayout来决定它的子视图控制器是否应该在导航栏/状态栏区域下可见。在UINavigationController上设置edgesForExtendedLayout本身并不会改变UINavigationController是否有一个44或64点高的导航栏区域。关于这个逻辑,请参见第4条。当使用工具栏或UITabBarController时,类似的布局逻辑适用于视图的底部。

  7. 如果你想做的只是阻止你的自定义子视图控制器在UINavigationController内部重叠导航栏,那么将edgesForExtendedLayout设置为UIRectEdgeNone(或者至少是一个掩码,不包括UIRectEdgeTop)。在视图控制器的生命周期中尽可能早地设置这个值。

  8. UINavigationController和UITabBarController也会尝试填充它的子视图层次结构中的表视图和集合视图的contentInsets。它以类似于第4条中的状态栏逻辑的方式完成此操作。有一种编程方法可以防止这种情况,为您的表视图和集合视图自动设置adjustsscrollviewinsets为NO(默认为YES)。这给Whisper和Riposte带来了一些严重的问题,因为我们使用contentInset调整来控制表视图的布局,以响应工具栏和键盘的移动。

  9. 重申一下:没有办法回到ios6风格的状态栏布局逻辑。为了接近这一点,你必须将应用程序的所有视图控制器移动到一个容器视图中,从屏幕顶部偏移20个点,故意在状态栏后面留下一个黑色视图来模拟旧的外观。这也是我们在《Riposte》和《Whisper》中所使用的方法。

  10. 苹果非常努力地确保你不会尝试第9条。他们想让我们重新设计我们所有的应用程序,使其覆盖状态栏。然而,出于用户体验和技术原因,有许多令人信服的争论,为什么这并不总是一个好主意。你应该做对用户最有利的事情,而不是简单地跟随平台的奇思妙想。

下面是广泛使用Storyboard的项目的另一种方法:

目标:

这种方法的目标是在iOS7中重新创建与在iOS6中相同的状态栏样式(见问题标题“iOS7状态栏回到iOS6样式?”)。

简介:

为了实现这一点,我们尽可能多地使用故事板,通过向下移动状态栏重叠的UI元素(在iOS 7下),同时使用增量来恢复iOS 6.1或更早版本的向下布局更改。在ios7中产生的额外空间然后被一个UIView占用,并将backgroundColor设置为我们选择的颜色。后者可以在代码中创建,也可以使用故事板(参见下面的替代方案)

假设:

为了在执行以下步骤时获得所需的结果,假设View controller-based status bar appearance被设置为NO,并且你的Status bar style被设置为“透明黑色风格(alpha为0.5)”或“不透明黑色风格”。这两种设置都可以在项目设置的“信息”下找到或添加。

步骤:

  • 添加一个子视图到用户界面窗口,作为你的状态栏背景。为了实现这一点,在你的AppDelegate的makeKeyAndVisible之后添加以下内容

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
    UIView *statusBarBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, yourAppsUIWindow.frame.size.width, 20)];
    statusBarBackgroundView.backgroundColor = [UIColor blackColor];
    [yourAppsUIWindow addSubview:statusBarBackgroundView];
    }
    
  • Since you programmatically added a background for iOS 7 ONLY, you will have to adjust the layout of your UI elements that are overlapped by the status bar accordingly whilst preserving their layout for iOS6. To achieve this, do the following:

    • Ensure that Use Autolayout is unchecked for your Storyboard (this is because otherwise "iOS 6/7 Deltas" is not shown in the Size Inspector). To do this:
      • select your Storyboard file
      • show Utilities
      • select "Show the File Inspector"
      • Under "Interface Builder Document" uncheck "Use Autolayout"
    • Optionally, to help you monitor the layout changes for both iOS 7 AND 6 as you apply them, select the "Assistant Editor", select "Preview" and "iOS 6.1 or earlier": enter image description here enter image description here
    • Now select the UI element you want to adjust so it isn't overlapped by the status bar anymore
    • Select "Show the Size Inspector" in the Utilities column
    • Reposition your UI element along the Y-axis by the same amount as the statusbar bg height: enter image description here
    • And change the iOS6/7 Deltas value for Y by the same NEGATIVE amount as the statusbar bg height (Note the change in the iOS 6 preview if you're using it): enter image description here

ALTERNATIVES:

To add even less code in storyboard-heavy projects and to have the statusbar background autorotate, instead of programmatically adding a background for your statusbar, you could add a colored view to each view controller that sits at the very top of said viewcontroller's main view. You would then change the height delta of this new view to the same negative amount as your view's height (to make it disappear under iOS 6).

The downside of this alternative (although maybe negligible considering the autorotate compatibility) is the fact that this extra view is not immediately visible if you are viewing your Storyboard for iOS 6. You would only know that it's there if you had a look at the "Document Outline" of the Storyboard.

对于Archy Holt的回答,有一个小的选择,更简单一点:

a.在info.plist中设置UIViewControllerBasedStatusBarAppearanceNO

b.在AppDelegateapplication:didFinishLaunchingWithOptions:中,调用:

if ([[UIDevice currentDevice].systemVersion floatValue] < 7)
{
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
}
else
{
// handling statusBar (iOS7)
application.statusBarStyle = UIStatusBarStyleLightContent;
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
self.window.clipsToBounds = YES;


// handling screen rotations for statusBar (iOS7)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidChangeStatusBarOrientationNotification:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
}

并添加方法:

- (void)applicationDidChangeStatusBarOrientationNotification:(NSNotification *)notification
{
// handling statusBar (iOS7)
self.window.frame = [UIScreen mainScreen].applicationFrame;
}

你也可以考虑子类化UIWindow来处理UIApplicationDidChangeStatusBarOrientationNotification本身。

解决方案:

通过重写方法在你的视图控制器或rootviewcontroller中设置它:

-(BOOL) prefersStatusBarHidden
{
return YES;
}

我非常简单的解决方案(假设你只支持垂直方向)是重新定义iOS版本7以下的应用程序窗口边界,在App委托didFinishLaunchingWithOptions方法中:

CGRect screenBounds = [[UIScreen mainScreen] bounds];
if ([HMService getIOSVersion] < 7) {
// handling statusBar (iOS6) by leaving top 20px for statusbar.
screenBounds.origin.y = 20;
self.window = [[UIWindow alloc] initWithFrame:screenBounds];
}
else {
self.window = [[UIWindow alloc] initWithFrame:screenBounds];
}

如果你正在使用接口构建器,试试这个:

在你的xib文件中:

1)选择主视图,设置背景颜色为黑色(或任何你想要状态栏的颜色)

< p > 2)确保背景是一个自包含的子视图,定位为控制器视图的顶级子视图。 < br > 移动你的背景成为控制器视图的直接子视图。检查自动调整面板,确保你已经锁定了所有的帧边,激活了两个灵活性轴,如果这是一个UIImageView,将内容模式设置为缩放填充。通过编程,这将转换为contentMode设置为UIViewContentModeScaleToFill,并将其自动调整掩码设置为(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight) < p > 3)现在将所有被锁定的东西上下移动20点,并设置iOS 6/7 delta Y为-20。 < br > 在自动缩放面板中,所有被锁定在顶部框架上的顶级子图层都需要向下移动20点,并将其iOS 6/7 delta Y设置为-20。(Cmd选择所有这些,并按下箭头20次-有更好的方法吗?)

4)调整上述所有具有弹性高度的项目的iOS 6/7 delta高度。 任何被锁定在框架顶部和底部并在自动大小调整面板中启用了灵活高度的项目也必须将其iOS 6/7 delta高度设置为20。这包括上面提到的背景视图。这似乎是违反直觉的,但由于这些应用的顺序,这是必要的。首先设置帧高度(基于设备),然后应用增量,最后根据所有子帧的偏移位置应用自动大小调整蒙版——仔细想想,这是有意义的

5)最后,被锁定在底部框架而不是顶部框架的项目根本不需要delta。

这将给你在iOS7和iOS6中相同的状态栏。

另一方面,如果你在保持iOS6兼容性的同时想要 iOS7样式化,则将背景视图的delta Y / delta height值设置为0。

要查看更多iOS7迁移信息,请阅读全文:http://uncompiled.blogspot.com/2013/09/legacy-compatible-offsets-in-ios7.html

更新(新解决方案)

本次更新是iOS 7导航栏问题的最佳解决方案。您可以设置导航栏颜色示例:FakeNavBar。backgroundColor = [UIColor redColor];

注意:如果你使用默认的导航控制器,请使用旧的解决方案。

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{


if(NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_7_0)
{
UIView *FakeNavBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
FakeNavBar.backgroundColor = [UIColor whiteColor];


float navBarHeight = 20.0;
for (UIView *subView in self.window.subviews) {


if ([subView isKindOfClass:[UIScrollView class]]) {
subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height - navBarHeight);
} else {
subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height);
}
}
[self.window addSubview:FakeNavBar];
}


return YES;


}

旧的解决方案-如果你使用以前的代码,请忽略下面的代码和图像

这是旧版本的iOS 7导航栏解决方案。

我用下面的代码解决了这个问题。这是用来添加状态栏的。 didFinishLaunchingWithOptions < / del > < / p >
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
UIView *addStatusBar = [[UIView alloc] init];
addStatusBar.frame = CGRectMake(0, 0, 320, 20);
addStatusBar.backgroundColor = [UIColor colorWithRed:0.973 green:0.973 blue:0.973 alpha:1]; //change this to match your navigation bar
[self.window.rootViewController.view addSubview:addStatusBar];
}

接口生成器这是当你打开iOS 6;它从0像素开始。

注意:iOS 6/7只有当你在详细信息窗格的“文件检查器”(最左边的图标)中取消对视图控制器的“使用自动布局”时才会出现增量

Enter image description here

苹果发布了技术Q& a QA1797:防止状态栏覆盖您的视图。它适用于iOS 6和iOS 7版本。

我在iOS 7中实现了iOS 6的状态栏。

在info.plist中设置UIViewControllerBasedStatusBarAppearance为NO

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中传递此代码

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
[application setStatusBarStyle:UIStatusBarStyleLightContent];
self.window.clipsToBounds =YES;
self.window.frame =  CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height);


//Added on 19th Sep 2013
NSLog(@"%f",self.window.frame.size.height);
self.window.bounds = CGRectMake(0,0, self.window.frame.size.width, self.window.frame.size.height);
}

它可能会把你所有的视图都压低20个像素。要克服这一点,请使用-(void)viewDidAppear:(BOOL)animated方法中的以下代码

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
CGRect frame=self.view.frame;
if (frame.size.height==[[NSUserDefaults standardUserDefaults] floatForKey:@"windowHeight"])
{
frame.size.height-=20;
}
self.view.frame=frame;
}

你必须在didFinishLauncing Method中设置窗口分配后的windowHeight Userdefaults值

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[[NSUserDefaults standardUserDefaults] setFloat:self.window.frame.size.height forKey:@"windowHeight"];

我已经看了很多很多很多教程来解决这个该死的问题。但是没有一个有用!以下是我的解决方案,对我来说很管用:

if( [[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f ) {
float statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
for( UIView *v in [self.view subviews] ) {
CGRect rect = v.frame;
rect.origin.y += statusBarHeight;
v.frame = rect;
}
}
逻辑很简单。我改变了所有孩子对自我的看法。视图为20像素。 这是所有。然后,屏幕截图就会像iOS 6一样显示出来。我讨厌iOS7的状态栏!~“~ < / p >
我的解决方案是在iOS 7上的窗口顶部添加一个高度为20点的UIView。 然后我在AppDelegate类中创建了一个方法来显示/隐藏“固态”状态栏背景。在application:didFinishLaunchingWithOptions:: < / p >
// ...


// Add a status bar background
self.statusBarBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.window.bounds.size.width, 20.0f)];
self.statusBarBackground.backgroundColor = [UIColor blackColor];
self.statusBarBackground.alpha = 0.0;
self.statusBarBackground.userInteractionEnabled = NO;
self.statusBarBackground.layer.zPosition = 999; // Position its layer over all other views
[self.window addSubview:self.statusBarBackground];


// ...
return YES;

然后我创建了一个方法来淡入/淡出黑色状态栏背景:

- (void) showSolidStatusBar:(BOOL) solidStatusBar
{
[UIView animateWithDuration:0.3f animations:^{
if(solidStatusBar)
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
self.statusBarBackground.alpha = 1.0f;
}
else
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
self.statusBarBackground.alpha = 0.0f;
}
}];
}

我现在要做的就是在需要时调用[appDelegate showSolidStatusBar:YES]

最简单的方法就是在最新的Xcode上安装一个旧的SDK。

如何安装旧SDK到最新的Xcode?

  1. 你可以从http://www.4shared.com/zip/NlPgsxz6/iPhoneOS61sdk.html或下载旧的Xcode并从其内容中获得SDK

  2. 解压并粘贴到/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/ sdk

  3. 重新启动xcode。

  4. 你现在可以在项目的构建设置中选择一个旧的SDK

希望对你有所帮助。这对我有用=)

由于使用presentViewController:animated:completion:会弄乱window.rootViewController.view,我必须找到一个不同的方法来解决这个问题。我终于让它与模态和旋转工作通过子类化我的rootViewController的UIView。

. h

@interface RootView : UIView


@end

00

@implementation RootView


-(void)setFrame:(CGRect)frame
{
if (self.superview && self.superview != self.window)
{
frame = self.superview.bounds;
frame.origin.y += 20.f;
frame.size.height -= 20.f;
}
else
{
frame = [UIScreen mainScreen].applicationFrame;
}


[super setFrame:frame];
}


- (void)layoutSubviews
{
self.frame = self.frame;


[super layoutSubviews];
}


@end

现在你有了iOS7动画的强大解决方案。

我在所有的视图控制器中都使用了这个,很简单。 在你所有的viewDidLoad方法中添加这行:

- (void)viewDidLoad{
//add this 2 lines:
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;


[super viewDidLoad];
}

隐藏状态栏的步骤:

1.转到您的应用程序信息。plist文件。

2.和设置,查看基于控制器的状态栏外观:布尔NO

希望我解决了状态栏问题.....

为了继续使用setStatusBarHidden:我使用这个类别:

@interface UIApplication (StatusBar)


-(void)setIOS7StatusBarHidden:(BOOL)statusBarHidden;


@end


@implementation UIApplication (StatusBar)


-(void)setIOS7StatusBarHidden:(BOOL)statusBarHidden{
if (!IOS7) {
[self setStatusBarHidden:statusBarHidden];
return;
}


if ([self isStatusBarHidden] == statusBarHidden) {
return;
}


[self setStatusBarHidden:statusBarHidden];
[self keyWindow].clipsToBounds = YES;
CGFloat offset = statusBarHidden ? 0 : 20;
[self keyWindow].frame =  CGRectMake(0,offset,[self keyWindow].frame.size.width,[self keyWindow].frame.size.height-offset);
[self keyWindow].bounds = CGRectMake(0, offset, [self keyWindow].frame.size.width,[self keyWindow].frame.size.height);
}


@end
我回答这个问题要迟到了,但我只是想分享我所做的,这基本上是 最简单的解决方案

找到你的info.plist文件和添加状态栏样式->透明黑色样式(Alpha 0.5)

现在,它开始了:-

在你的AppDelegate.m中添加这段代码

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Whatever your code goes here
if(kDeviceiPad){


//adding status bar for IOS7 ipad
if (IS_IOS7) {
UIView *addStatusBar = [[UIView alloc] init];
addStatusBar.frame = CGRectMake(0, 0, 1024, 20);
addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //change this to match your navigation bar
[self.window.rootViewController.view addSubview:addStatusBar];
}
}
else{


//adding status bar for IOS7 iphone
if (IS_IOS7) {
UIView *addStatusBar = [[UIView alloc] init];
addStatusBar.frame = CGRectMake(0, 0, 320, 20);
addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //You can give your own color pattern
[self.window.rootViewController.view addSubview:addStatusBar];
}


return YES;
}

我发现这里是这个导航栏问题在iOS7的最佳替代方案和解决方案!!

http://www.appcoda.com/customize-navigation-status-bar-ios-7/

我希望它能消除我们所有的疑问和担忧。

这可能是一个压倒性的问题,如果你使用自动布局,因为你不能直接操作帧。有一个简单的解决方案,不需要太多的工作。

我最终在一个实用程序类中编写了一个实用程序方法,并从所有视图控制器的viewDidLayoutSubviews方法中调用它。

+ (void)addStatusBarIfiOS7:(UIViewController *)vc
{
if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
CGRect viewFrame = vc.view.frame;
if(viewFrame.origin.y == 20) {
//If the view's y origin is already 20 then don't move it down.
return;
}
viewFrame.origin.y+=20.0;
viewFrame.size.height-= 20.0;
vc.view.frame = viewFrame;
[vc.view layoutIfNeeded];
}
}

在视图控制器中覆盖你的viewDidLayoutSubviews方法,你想要的状态栏。它会让你通过自动布局的负担。

- (void)viewDidLayoutSubviews
{
[[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
[super viewDidLayoutSubviews];
[MyUtilityClass addStatusBarIfiOS7:self];
}

试试这个简单的方法....

步骤1:在单个viewController中更改

[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque];

步骤2:改变整个应用程序

info.plist
----> Status Bar Style
--->UIStatusBarStyle to UIStatusBarStyleBlackOpaque

步骤3:也在每个viewWillAppear中添加这个,以调整iOS7statusbar高度

    [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
if ([[UIDevice currentDevice].systemVersion floatValue] >= 7) {
CGRect frame = [UIScreen mainScreen].bounds;
frame.origin.y+=20.0;
frame.size.height-= 20.0;
self.view.frame = frame;
[self.view layoutIfNeeded];
}

这可能太晚了,但我有一些东西可以贡献,这可能会帮助到某人,我试图子类化UINavigationBar,并想让它看起来像ios 6黑色状态栏和白色状态栏文本。

以下是我发现的方法

        self.navigationController?.navigationBar.clipsToBounds = true
self.navigationController?.navigationBar.translucent = false
self.navigationController?.navigationBar.barStyle = .Black
self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor()

它使我的状态栏背景为黑色,状态栏文本为白色,导航栏为白色。

iOS 9.3, XCode 7.3.1