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

Posted

技术标签:

【中文标题】iOS 7 状态栏在 iPhone 应用程序中回到 iOS 6 默认样式?【英文标题】:iOS 7 status bar back to iOS 6 default style in iPhone app? 【发布时间】:2013-08-20 03:10:55 【问题描述】:

ios 7 中,UIStatusBar 的设计方式使其与视图合并,如下所示:

(界面由Tina Tavčar设计)

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

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

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

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

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

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

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

【问题讨论】:

遗憾的是,iOS 7 中不推荐使用黑色状态栏 我同意@GangstaGraham。这些颜色只是美丽!要回答你的问题,恐怕你不能。之所以现在这样设计状态栏,是因为半透明是 iOS 的新事物,它旨在通过说它位于某物之上,从而赋予应用程序“深度”,因此下方有一些东西。 您是否尝试过将preferredStatusBarStyle 设置为UIStatusBarDefault?结帐iOS 7 UIViewController Documentation UIStatusBarDefault 用于状态栏只会使其内容变为黑色。它不会使其功能恢复到 iOS6 中的方式。 这个运气好吗?我喜欢 iOS7,但这件事让我发疯了! 【参考方案1】:

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

UIStatusBarStyleNone 或在目标设置中设置。

【讨论】:

在哪里指定 UIStatusbarstylenone【参考方案2】:

2013 年 9 月 19 日更新:

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

更正了NSNotificationCenter 语句中的拼写错误

2013 年 9 月 12 日更新:

UIViewControllerBasedStatusBarAppearance 更正为NO

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

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

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

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

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

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

为了:

    检查是否是 iOS 7。

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

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

    通过移动和调整应用程序的窗口框架大小,营造一种状态栏占用空间的错觉,就像在 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 语句来检测应用的屏幕方向(纵向、上下颠倒、横向左或横向右)并分别改变应用的窗口框架以创建 iOS 6 状态栏错觉。

更改状态栏的背景颜色:

添加

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

【讨论】:

旋转时会中断。只是提醒 @JesseNaugher 我建议以编程方式将垂直间距约束从 0 修改为 20。它可以旋转。 关于如何避免导航栏扩大 20 像素的任何想法?这个解决方案对我来说很好,但我的导航栏太高了 20 像素。 @ArchyHolt:您的简单解决方案对我有用,除非我提供模态视图控制器。一旦模态视图控制器被解除,剩余的视图现在位于状态栏下方。我已经在一个新的示例项目中复制了这一点,以确保没有其他时髦的事情发生。我在想也许你更高级的解决方案在这里可能有用,但不确定什么通知会起作用。有什么想法吗? 关闭模式视图控制器后视图会重置。 :(【参考方案3】:

如果您不希望视图控制器与状态栏(和导航栏)重叠,请取消选中 Interface Builder 中的“在顶部栏下延伸边缘”框Xcode 5。

【讨论】:

这只有在你使用故事板时才有可能 它仅适用于容器 vcs,例如导航控制器或标签栏控制器 edgesForExtendedLayout 仅由容器视图控制器(如 UINavigationController)使用,以确定其子视图是否应与父 chrome 重叠。在 UIWindow 的根视图控制器上设置此属性不会执行任何操作。请参阅上面的答案:***.com/questions/18294872/… 你如何为 UITabBarController @Andrea 做到这一点?谢谢。 @KarenAnne 取决于您是通过编程方式还是使用情节提要。以编程方式,您只需将edgesForExtent 属性设置为您在UITabBarViewController 中显示的视图控制器中您喜欢的属性,但是为了不存在状态栏问题,您必须在第一个UITabbarController 中加载一个uinavigationcontroller。在这里检查。 developer.apple.com/library/ios/documentation/UserExperience/…【参考方案4】:

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

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

【讨论】:

【参考方案5】:

这是从 a blog post I wrote 交叉发布的,但这里是 iOS 7 上状态栏、导航栏和容器视图控制器的完整概要:

    没有办法保留 iOS 6 样式的状态栏布局。在 iOS 7 上,状态栏将始终与您的应用重叠

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

    状态栏外观由两个互斥的基础路径之一控制:您可以以传统方式以编程方式设置它们,或者 UIKit 将根据 UIViewController 的一些新属性为您更新外观。后一个选项默认开启。检查您应用的 plist 值是否为“基于 ViewController 的状态栏外观”,以查看您使用的是哪一个。如果将此值设置为 YES,则应用程序中的每个***视图控制器(标准 UIKit 容器视图控制器除外)都需要覆盖 PreferredStatusBarStyle,返回默认样式或灯光样式。如果将 plist 值编辑为 NO,则可以使用熟悉的 UIApplication 方法管理状态栏外观。

    UINavigationController 将根据一组相当奇怪且未记录的约束将其 UINavigationBar 的高度更改为 44 点或 64 点。如果 UINavigationController 检测到其视图框架的顶部与其 UIWindow 的顶部在视觉上是连续的,则它会绘制高度为 64 磅的导航栏。如果其视图的顶部与 UIWindow 的顶部不连续(即使仅相差一个点),则它以“传统”方式绘制其导航栏,高度为 44 点。 此逻辑由 UINavigationController 执行,即使它是应用程序的视图控制器层次结构中的多个子级。没有办法阻止这种行为。

    1234563框架(0,20,320,44),在您的自定义图像上方留下 20 个不透明的黑色空间点。这可能会让您误以为自己是绕过规则 1 的聪明开发人员,但您错了。导航栏仍然是 64 点高。将 UINavigationController 嵌入到幻灯片显示样式的视图层次结构中可以使这一点非常清晰。

    当心 UIViewController 的命名混淆的 edgesForExtendedLayout 属性。在大多数情况下,调整 edgeForExtendedLayout 没有任何作用。 UIKit 使用此属性的唯一方法是,如果您将视图控制器添加到 UINavigationController,则 UINavigationController 使用 edgesForExtendedLayout 来确定其子视图控制器是否应该在导航栏/状态栏区域下方可见。在 UINavigationController 本身上设置 edgesForExtendedLayout 不会改变 UINavigationController 是否具有 44 点或 64 点高的导航栏区域。有关该逻辑,请参见#4。使用工具栏或 UITabBarController 时,类似的布局逻辑适用于视图底部。

    1234563在视图控制器的生命周期中尽早设置此值。

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

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

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

【讨论】:

只是想补充一点,您可以将约束添加到视图顶部的任何内容以附加到顶部布局指南 - 这将在状态栏后面留下一个空白区域(您可以用你想要的任何颜色填充),但也会允许视图在 iOS 6 中自动调整到正确的位置。这样您就不必在代码中手动调整视图的位置。 这是一个绝妙的解决方案。你暴露了我对 AutoLayout 的无知。最好继续这样做。 如果您将对象的顶部空间放置在顶部布局指南的边缘下方,您可以使用约束控件将垂直间距约束添加到最近的邻居,这将成为顶部布局指南。或者,您可以使用 ctrl+click 从您的对象到顶部布局指南显式添加垂直间距约束。 @BreadicalMD 我不明白的一部分是 -topLayoutGuide 在 iOS 6 上不可用,这是否意味着您需要在 iOS 7 和 6 上使用不同的自动布局约束? 很好的答案...但我有一个疑问 1) UINavigationController 改变高度部分。请多解释一下。谢谢【参考方案6】:

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

目标:

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

总结:

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

假设:

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

步骤:

向 UIWindow 添加一个子视图作为您的状态栏背景。为此,请将以下内容添加到您的 AppDelegate 的 application: 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 布局。为此,请执行以下操作:

确保您的 Storyboard 中未选中 Use Autolayout(这是因为否则“大小检查器”中不会显示“iOS 6/7 Deltas”)。去做这个: 选择您的 Storyboard 文件 显示实用程序 选择“显示文件检查器” 在“Interface Builder Document”下取消选中“Use Autolayout” (可选)为了帮助您在应用 iOS 7 和 6 时监控布局更改,请选择“Assistant Editor”,选择“Preview”和“iOS 6.1 或更早版本”: 现在选择您要调整的 UI 元素,使其不再与状态栏重叠 在实用程序列中选择“显示尺寸检查器” 将 UI 元素沿 Y 轴重新定位,其量与状态栏 bg 高度相同: 并将 Y 的 iOS6/7 Deltas 值更改为与状态栏 bg 高度相同的 NEGATIVE 量(如果您正在使用它,请注意 iOS 6 预览中的更改):

替代方案:

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

这种替代方案的缺点(尽管考虑到自动旋转兼容性可能可以忽略不计)是,如果您正在查看适用于 iOS 6 的 Storyboard,则不会立即看到这个额外的视图。只有看过之后,您才会知道它的存在在情节提要的“文档大纲”中。

【讨论】:

【参考方案7】:

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

一个。在 info.plist 中将 UIViewControllerBasedStatusBarAppearance 设置为 NO

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 本身。

【讨论】:

您对 presentViewController:animated:completion: 有问题吗? @TùngĐỗ 是的,所以我做了一个更好的替代方案:***.com/questions/18294872/…【参考方案8】:

解决方案:

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

-(BOOL) prefersStatusBarHidden
    
        return YES;
    

【讨论】:

不错的解决方案。完全删除栏。可能并不总是理想的用户体验,但可行。 简直太棒了。完美地为我工作。 场景:当我全屏播放视频后切换回我的 UIVIew 时,底部会出现一个黑条,它只是状态栏的大小,尽管我已经在使用状态栏了。我完全删除了状态栏,现在问题已解决。 我只用这个方法成功过【参考方案9】:

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

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

【讨论】:

您的代码只是将“y”从 0 移动到 20,但不会相应地调整高度,因此您应该添加 screenBounds.size.height -= 20;就在 screenBounds.origin.y = 20; 之后【参考方案10】:

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

在您的 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

【讨论】:

使用自动布局时没有增量【参考方案11】:

更新(新解决方案)

本次更新是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 仅在您在详细信息窗格的“文件检查器”(最左侧的图标)中取消选中视图控制器的“使用自动布局”时才会出现。

【讨论】:

你成就了我的一天。请 +1 寻求帮助! 请注意:iOS 6/7 Delta 仅在您在详细信息窗格的“文件检查器”(最左侧图标)中取消选中视图控制器的“使用自动布局”时才会出现。 非常感谢!你帮我省了很多麻烦! 谁说不能维护 iOS 6 风格的状态栏布局,你可以通过@TacettinÖzbölük 的方式来做到这一点...感谢 mate 这个 awsum 解决方案。 不错的一个!另外,请注意苹果现在更喜欢这个:if (NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_6_1) 【参考方案12】:

Apple 发布了 Technical Q&A QA1797: Preventing the Status Bar from Covering Your Views。它适用于 iOS 6 和 iOS 7 版本。

【讨论】:

Apple 假设每个人都在使用自动布局。自动布局在 Xcode 4 中很糟糕,而 Xcode 5 才刚刚发布,所以这是一个可疑的假设。 但在未来,这是一个更好的解决方案,然后调整根窗口或状态栏的框架。 据我所知,如果您的 rootViewController 是 splitViewController,Apple 的解决方案将不起作用。【参考方案13】:

我已经在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"];

【讨论】:

一个更好的方法是让你的 UINavigationBar 的height 等于 64 而不是 44。然后你的栏会像苹果的应用一样一直延伸到顶部。 @AaronBrager 但我的要求是显示 iOS 6 风格的状态栏。 你能添加iOS 7横向方向的解决方案吗?我也在做同样的事情。但它不适用于 iOS 7 Landscape。 @DesertRose THX!这对我有用,但它切断了底部的 uitabbar。我有一个基于标签栏控制器的应用程序,它有 3 个视图,其中 2 个是 tableviewcontrollers。 直到我旋转设备(我的 iOS 7 设备是 iPad),这完美地修复了它。但是一旦我旋转,黑条就会保持在原来的位置,并且“视图”(对不起,如果这是错误的技术术语,我是 PhoneGap/web 人)保持其缩小的高度——除了它不再是高度,而是宽度。此解决方案不支持旋转,但它是我见过的最好的解决方案 - 如何改进以观察设备旋转?谢谢!【参考方案14】:

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

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的状态栏! ~"~

【讨论】:

我应该在哪里添加这个?应用内委托确实启动了选项? 当我这样做时,我的状态栏变成白色【参考方案15】:

我的解决方案是在 iOS 7 上在窗口顶部添加一个高度为 20 磅的 UIView。 然后我在我的 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]

【讨论】:

【参考方案16】:

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

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

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

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

    重启xcode。

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

希望对您有所帮助。它对我有用 =)

【讨论】:

为我工作。感谢@marcelosalloum,但仍在为我的phonegap (uiwebview) 应用程序寻找解决方法,以支持iOS7 的透明状态栏,以便将来更新我的应用程序。再次感谢。 ;) @marcellosaloum,您确定该应用会被 Apple 接受吗?他们说使用 XCode 4 编译的应用程序将不再被接受......事实上这意味着 iOS 6 SDK。 我的应用确实被接受了,因为 Xcode5 可以编译旧的 iOS SDK。我不确定 AppStore 是否会拒绝 Xcode4 构建的应用程序,但 (Xcode4 != iOS 6 SDK) 如您所说。 是在 2 月 1 日之后吗?在那一天,Apple 强制要求这样做。 不,去年最后一次碰那个代码,伙计们。不知道苹果已经强制执行(虽然不高兴知道)。你能把上面说的链接贴在这里吗?干杯【参考方案17】:

由于使用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 动画解决方法。

【讨论】:

【参考方案18】:

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

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

    [super viewDidLoad];

【讨论】:

工作起来就像一个魅力,而且非常容易。在 ruby​​ 运动中,在调用 super 之前使用: self.edgesForExtendedLayout = UIRectEdgeNone if respondsToSelector("edgesForExtendedLayout")【参考方案19】:

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

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

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

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

【讨论】:

【参考方案20】:

为了继续使用 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

【讨论】:

【参考方案21】:

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

首先-> 转到您的info.plist 文件并添加状态栏样式->透明黑色样式(Alpha of 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;
   

【讨论】:

【参考方案22】:

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

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

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

【讨论】:

【参考方案23】:

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

我最终在实用程序类中编写了一个实用程序方法,并从所有视图控制器的 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];

【讨论】:

【参考方案24】:

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

第一步:换单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];
    

【讨论】:

【参考方案25】:

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

【讨论】:

以上是关于iOS 7 状态栏在 iPhone 应用程序中回到 iOS 6 默认样式?的主要内容,如果未能解决你的问题,请参考以下文章

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

iOS 7状态栏在iPhone应用程序中恢复到iOS 6默认样式?

iPhone模拟器保持状态栏在视图中

主/详细故事板项目中的 IOS 导航栏在 ipad 上是透明的,但在 iphone 上不透明

iOS 获取状态栏、导航栏、tabBar高度

iOS 7 导航栏在翻转水平 Segue 上跳转