293

在 iOS 7UIStatusBar中,它的设计方式是与视图合并,如下所示:

由 Tina Tavčar 设计的 GUI (由Tina Tavčar设计的 GUI )

  • 这很酷,但是当您在视图的顶部有一些东西时,它会有点混乱您的视图,并且它会与状态栏重叠。

  • 是否有一个简单的解决方案(例如在 info.plist 中设置属性)可以将其工作方式 [不重叠] 更改回 iOS6 中的方式?

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

  • 如果有人可以为此提供一个单行解决方案,我将非常高兴。

PS我知道我可以通过做一些事情来隐藏状态栏

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

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

4

25 回答 25

448

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

  1. 没有办法保留 iOS 6 风格的状态栏布局。状态栏将始终与您在 iOS 7 上的应用程序重叠

  2. 不要将状态栏外观与状态栏布局混淆。外观(浅色或默认)不会影响状态栏的布局方式(框架/高度/重叠)。还需要注意的是,系统状态栏不再有任何背景颜色。当 API 引用 UIStatusBarStyleLightContent 时,它们表示清晰背景上的白色文本。UIStatusBarStyleDefault 是清晰背景上的黑色文本。

  3. 状态栏外观由两个互斥的基础路径之一控制:您可以以传统方式以编程方式设置它们,或者 UIKit 将根据 UIViewController 的一些新属性为您更新外观。后一个选项默认开启。检查您应用的 plist 值是否为“基于 ViewController 的状态栏外观”,以查看您使用的是哪一个。如果将此值设置为 YES,则应用程序中的每个顶级视图控制器(标准 UIKit 容器视图控制器除外)都需要覆盖首选状态栏样式,返回默认样式或灯光样式。如果将 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 属性。在大多数情况下,调整 edgeForExtendedLayout 没有任何作用。UIKit 使用此属性的唯一方法是,如果您将视图控制器添加到 UINavigationController,则 UINavigationController 使用 edgesForExtendedLayout 来确定其子视图控制器是否应该在导航栏/状态栏区域下方可见。在 UINavigationController 本身上设置 edgesForExtendedLayout 不会改变 UINavigationController 是否具有 44 点或 64 点高的导航栏区域。有关该逻辑,请参见#4。使用工具栏或 UITabBarController 时,类似的布局逻辑适用于视图的底部。

  7. 如果您要做的只是防止您的自定义子视图控制器在 UINavigationController 内覆盖导航栏,则将 edgesForExtendedLayout 设置为 UIRectEdgeNone(或至少一个不包括 UIRectEdgeTop 的掩码)。在视图控制器的生命周期中尽早设置此值。

  8. UINavigationController 和 UITabBarController 还将尝试在其子视图层次结构中填充表视图和集合视图的 contentInsets。它以类似于#4 中的状态栏逻辑的方式执行此操作。有一种编程方式可以防止这种情况发生,通过将表视图和集合视图的自动调整滚动视图插入设置为否(默认为是)。这给 Whisper 和 Riposte 带来了一些严重的问题,因为我们使用 contentInset 调整来控制表格视图的布局以响应工具栏和键盘的移动。

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

  10. Apple 正在努力确保您不会尝试执行 #9。他们希望我们重新设计所有应用程序以覆盖状态栏。然而,出于用户体验和技术原因,有许多令人信服的论点,为什么这并不总是一个好主意。您应该为您的用户做最好的事情,而不是简单地跟随平台的奇思妙想。

于 2013-09-17T16:49:18.063 回答
123

2013 年 9 月 19 日更新:

通过添加修复缩放错误 self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);

更正了NSNotificationCenter声明中的错别字


2013 年 9 月 12 日更新:

更正UIViewControllerBasedStatusBarAppearanceNO

为具有屏幕旋转功能的应用添加了解决方案

添加了一种更改状态栏背景颜色的方法。


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

但是,我们总是可以编写一些代码并将状态栏变成类似 iOS6 的,这是我能想到的最短方法:

  1. 设置UIViewControllerBasedStatusBarAppearanceNOin info.plist(选择不让视图控制器调整状态栏样式,以便我们可以使用 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;
    


为了:

  1. 检查它是否是iOS 7。

  2. 将状态栏的内容设置为白色,而不是 UIStatusBarStyleDefault。

  3. 避免显示其框架超出可见边界的子视图(对于从顶部动画到主视图的视图)。

  4. 通过移动和调整应用程序的窗口框架大小来创建状态栏占用空间的错觉,就像它在 iOS 6 中一样。


对于具有屏幕旋转功能的应用,

使用 NSNotificationCenter 通过添加来检测方向变化

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

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

- (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 语句来检测应用的屏幕方向(Portrait、Upside Down、Landscape Left 或 Landscape Right)并分别改变应用的窗口框架以创建 iOS 6 状态栏错觉。


要更改状态栏的背景颜色:

添加

 @property (retain, nonatomic) UIWindow *background;

在您的班级中AppDelegate.h创建background一个属性并防止 ARC 释放它。(如果您不使用 ARC,则不必这样做。)

之后,您只需要在以下位置创建 UIWindow if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)

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

别忘了@synthesize background;@implementation AppDelegate

于 2013-08-22T17:38:04.533 回答
41

更新(新解决方案)

本次更新是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

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];
}

对于Interface Builder,这适用于使用 iOS 6 打开时;它从 0 像素开始。

注意:iOS 6/7 Delta 仅在您在详细信息窗格的“文件检查器”(最左侧的图标)中取消选中视图控制器的“使用自动布局”时才会出现。

在此处输入图像描述

于 2013-09-23T18:35:28.413 回答
26

解决方案 :

通过覆盖方法将其设置在您的视图控制器或根视图控制器中:

-(BOOL) prefersStatusBarHidden
    {
        return YES;
    }
于 2013-09-18T13:38:18.147 回答
17

这是广泛使用情节提要的项目的另一种方法:

目标:

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

概括:

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

假设:

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

脚步:

  • 将子视图添加到 UIWindow 以用作您的状态栏背景。为此,请将以下内容添加到您的 AppDelegateapplication: didFinishLaunchingWithOptions:之后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];
    }
    
  • 由于您仅以编程方式为 iOS 7 添加了背景,因此您必须相应地调整与状态栏重叠的 UI 元素的布局,同时保留它们的 iOS6 布局。为此,请执行以下操作:

    • 确保Use Autolayout未选中您的 Storyboard(这是因为“iOS 6/7 Deltas”不会显示在 Size Inspector 中)。去做这个:
      • 选择您的故事板文件
      • 显示实用程序
      • 选择“显示文件检查器”
      • 在“Interface Builder Document”下取消选中“Use Autolayout”
    • 或者,为了帮助您在应用 iOS 7 和 6 时监控布局更改,请选择“Assistant Editor”,选择“Preview”和“iOS 6.1 or later”: 在此处输入图像描述 在此处输入图像描述
    • 现在选择您要调整的 UI 元素,使其不再与状态栏重叠
    • 在 Utilities 列中选择“Show the Size Inspector”
    • 将 UI 元素沿 Y 轴重新定位,与状态栏 bg 高度相同: 在此处输入图像描述
    • 并将 Y 的 iOS6/7 Deltas 值更改为与状态栏 bg 高度相同的 NEGATIVE 量(如果您使用它,请注意 iOS 6 预览中的更改): 在此处输入图像描述

备择方案:

要在情节提要繁重的项目中添加更少的代码并让状态栏背景自动旋转,而不是以编程方式为状态栏添加背景,您可以为位于所述视图控制器主视图顶部的每个视图控制器添加一个彩色视图。然后,您可以将此新视图的高度增量更改为与您的视图高度相同的负数(使其在 iOS 6 下消失)。

这种替代方案的缺点(尽管考虑到自动旋转兼容性可能可以忽略不计)是,如果您正在查看 iOS 6 的 Storyboard,则不会立即看到这个额外的视图。只有查看“故事板的文档大纲”。

于 2013-09-17T18:31:59.147 回答
12

如果您不希望视图控制器与状态栏(和导航栏)重叠,请取消选中Xcode 5的Interface Builder中的“Extend Edges Under Top Bars”框。

取消选中顶部栏下的延伸边缘

于 2013-09-12T22:21:30.343 回答
11

Apple 发布了技术问答 QA1797:防止状态栏覆盖您的视图。它适用于 iOS 6 和 iOS 7 版本。

于 2013-09-25T07:58:20.513 回答
8

我已经查看了很多很多很多很多教程来解决这个该死的问题。但它们都不起作用!这是我的解决方案,它对我有用:

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;
    }
}

逻辑很简单。我将 self.view 上的所有子视图移动 20 像素。就这样。然后,屏幕截图将像 iOS 6 一样显示。我讨厌iOS7的状态栏!~~"~

于 2013-09-27T07:55:12.837 回答
6

Archy Holt 答案的一个小替代方案,更简单一点:

一个。UIViewControllerBasedStatusBarAppearanceNOinfo.plist 中设置

湾。在AppDelegate'sapplication: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自己。

于 2013-09-18T09:21:05.150 回答
5

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

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

    [super viewDidLoad];
}
于 2013-10-22T15:40:58.877 回答
4

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

Step 1 : 换单viewController

[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque];

第 2 步:更改整个应用程序

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

第 3 步:还要在每个中添加这个viewWillAppear以调整statusbar高度iOS7

    [[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];
    }
于 2014-04-15T09:04:15.347 回答
3

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

看看 Stack Overflow 问题Interface Builder: What are the UIView's Layout iOS 6/7 Deltas for? .

于 2013-09-16T08:04:10.957 回答
3

我在 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 方法中设置 windowHeight Userdefaults 值,例如

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[[NSUserDefaults standardUserDefaults] setFloat:self.window.frame.size.height forKey:@"windowHeight"];
于 2013-09-27T07:05:01.337 回答
2

如果您使用的是界面生成器,请尝试以下操作:

在您的 xib 文件中:

1)选择主视图,将背景颜色设置为黑色(或您希望状态栏为任何颜色

2)确保背景是一个独立的子视图,定位为控制器视图的顶级子视图。
移动您的背景以成为控制器视图的直接子级。检查自动调整大小面板以确保您已锁定所有框架边缘,激活两个灵活性轴,如果这是 UIImageView,请将内容模式设置为 Scale to fill。以编程方式,这将转换为 contentMode 设置为 UIViewContentModeScaleToFill 并将其自动调整大小掩码设置为 (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)。

3) 现在将所有被锁定的东西从上向下移动 20 分,并将 iOS 6/7 delta Y 设置为 -20。
所有在自动调整大小面板中锁定到顶部框架的顶级子项都需要向下移动 20pts 并将其 iOS 6/7 delta Y 设置为 -20。(Cmd 选择所有这些,然后单击向下箭头 20 次 - 有没有更好的方法?)

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

5)最后,锁定到底部框架但不是顶部框架的项目根本不需要增量。

这将在 iOS7 和 iOS6 中为您提供相同的状态栏。

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

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

于 2013-09-23T00:30:31.400 回答
2

我的解决方案是在 iOS 7 上添加一个UIView高度为 20 点的窗口顶部。然后我在 AppDelegate 类中创建了一个方法来显示/隐藏“实心”状态栏背景。在application:didFinishLaunchingWithOptions:

// ...

// 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]在需要时打电话。

于 2013-09-27T21:12:56.363 回答
2

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

我最终在实用程序类中编写了一个实用程序方法,并从所有视图控制器的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];
}
于 2014-03-28T17:18:43.117 回答
1

最简单的方法是将旧的 SDK 安装到最新的 Xcode。

如何将旧版 SDK 安装到最新版 Xcode?

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

  2. 将此文件夹解压缩并粘贴到 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs

  3. 重新启动 xcode。

  4. 您现在可以在项目的构建设置中选择较旧的 SDK

希望它可以帮助你。它对我有用=)

于 2013-10-03T19:06:25.263 回答
1

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

首先-> 转到您的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;
   }
于 2014-02-26T06:39:50.667 回答
1

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

。H

@interface RootView : UIView

@end

.m

@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 动画解决方法。

于 2013-10-08T16:47:14.403 回答
0

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

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

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

于 2014-03-26T06:30:30.923 回答
0

为了继续使用 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
于 2014-02-08T21:25:46.893 回答
0

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

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];
}
于 2013-09-19T14:55:07.893 回答
0

在 iOS 7 中隐藏状态栏的步骤:

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

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

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

于 2014-01-30T11:43:30.083 回答
0

您可以一起隐藏状态栏。所以你的应用程序将是全屏的。我认为这是你会得到的最好的。

UIStatusBarStyleNone或在目标设置中设置。

于 2013-08-22T16:29:41.083 回答
0

分享这可能为时已晚,但我有一些贡献可能对某人有所帮助,我试图对 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

于 2016-05-31T11:16:30.377 回答