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


292

在iOS 7中,UIStatusBar其设计方式是将其与如下视图合并:

由TinaTavčar设计的GUI (GUI由TinaTavčar设计)

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

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

  • 我知道一个更直接的解决方案是self.view.center.x为每个单个视图控制器增加20个点,但是更改它们将使其他尺寸变大(设置不同self.view.center.x会导致自定义序列等问题),突然变成了繁琐的工作最好避免。

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

附言:我知道我可以通过执行以下操作来隐藏状态栏:

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

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


6
可悲的是,黑色状态栏已在ios 7中弃用
i_duhh_bomb 2013年

我会同意@GangstaGraham。那些颜色真漂亮!要回答您的问题,恐怕您不能。状态栏之所以像现在这样设计,是因为半透明性是iOS的新事物,它的目的是通过说它位于某个事物之上,从而为应用程序提供“深度”,因此其下方是一些事物。
科尔·约翰逊

您是否尝试过将preferredStatusBarStyle设置为UIStatusBarDefault?结帐iOS 7 UIViewController文档
theaob

1
具有UIStatusBarDefault状态栏只会使其内容变为黑色。它不会使其功能恢复到iOS6中的状态。
吖奇说-何魏奇Archy Will He

2
有运气吗?我爱iOS7,但是这件事使我发疯!
Mihai Fratu

Answers:


449

这是我写的博客文章的交叉发布,但这是iOS 7上状态栏,导航栏和容器视图控制器的完整摘要:

  1. 无法保留iOS 6样式状态栏的布局。状态栏将始终在iOS 7上与您的应用程序重叠

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

  3. 状态栏外观是通过两个互斥的基本路径之一控制的:您可以以传统方式通过编程方式设置它们,或者UIKit将基于UIViewController的一些新属性为您更新外观。默认情况下,后一个选项处于启用状态。检查应用程序的“基于ViewController的状态栏外观”的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属性。在大多数情况下,调整edgeForExtendedLayout不会执行任何操作。UIKit使用此属性的唯一方法是,如果将视图控制器添加到UINavigationController,则UINavigationController使用edgeForExtendedLayout来确定其子视图控制器在导航栏/状态栏区域下方是否可见。在UINavigationController本身上设置edgeForExtendedLayout不会改变UINavigationController是否具有44或64点高的导航栏区域。有关该逻辑,请参见#4。使用工具栏或UITabBarController时,类似的布局逻辑也适用于视图的底部。

  7. 如果您要做的只是防止自定义子视图控制器在UINavigationController内时在导航栏上重叠,则将edgeForExtendedLayout设置为UIRectEdgeNone(或至少将UIRectEdgeTop排除在外的遮罩)。在视图控制器的生命周期中尽早设置此值。

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

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

  10. 苹果正在竭尽全力确保您不要尝试做#9。他们希望我们重新设计所有应用程序,以隐藏状态栏。但是,出于用户体验和技术原因,有许多令人信服的论点,为什么这并不总是一个好主意。您应该做最适合您的用户的事情,而不仅仅是遵循平台的异想天开。


35
只是想补充一点,您可以在视图顶部的任何位置添加约束,以附加到顶部布局指南-这将在状态栏后面留下空白(您可以用所需的任何颜色填充该空白)但也会允许视图在iOS 6中自动调整为正确的位置。这样,您不必手动调整视图在代码中的位置。
BreadicalMD 2013年

4
那是一个绝妙的解决方案。您暴露了我对AutoLayout的无知。最好继续做下去。
jaredsinclair 2013年

1
如果将对象的顶部空间放置在顶部布局向导的边缘下方,则可以使用约束控件向最近的邻居添加垂直间距约束,该约束现在将成为顶部布局向导。或者,您可以使用ctrl + click从对象到顶部布局指南来显式添加垂直间距约束。
BreadicalMD 2013年

2
@BreadicalMD我不了解的一部分是-topLayoutGuide在iOS 6上不可用,这是否意味着您需要在iOS 7和6上使用不同的“自动布局”约束?
杰里米

1
很好的答案...但是我有一个疑问:1)UINavigationController更改了高度部分。请再解释一下。谢谢
user1010819 13-10-31

122

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语句以检测应用程序的屏幕方向(纵向,上下颠倒,左横向或右横向)并分别更改应用的窗口框架,以创建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


3
旋转中断。只是抬起头
Jesse Naugher 2013年

2
@JesseNaugher我建议以编程方式将“垂直间距约束”从0修改为20。它将旋转。
专家

2
关于如何避免导航栏扩展20个像素的想法?这个解决方案对我来说很好,但是我的导航栏太高了20像素。
simonbs 2013年

4
@ArchyHolt:您的简单解决方案对我有用,除了当我介绍一个模态视图控制器时。解除模式视图控制器后,其余视图现在位于状态栏下。我在一个新的示例项目中重现了此内容,以确保没有其他时髦的事情发生。我在想,也许您更高级的解决方案在这里可能有用,但不确定会发出什么通知。有任何想法吗?
markdorison

4
关闭模态视图控制器后,视图将重置。:(
KarenAnne 2013年

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像素开始。

注意:仅当在详细信息窗格的“文件检查器”(最左侧的图标)中取消为View Controller选中“使用自动布局”时,iOS 6/7增量才会出现。

在此处输入图片说明


6
您过得很愉快。请+1帮助!
Niru Mukund Shah 2013年

5
请注意:仅当在详细信息窗格的“文件检查器”(最左侧的图标)中取消为View Controller选中“使用自动布局”时,iOS 6/7增量才会出现。
马特

1
非常感谢!你救了我很多麻烦!
neowinston 2013年

2
谁说无法维护iOS 6样式状态栏的布局,您可以通过@TacettinÖzbölük的方式来完成此工作...感谢mate提供的awsum解决方案。
Vizllx

1
好一个!同样,只是要注意苹果现在喜欢它:if(NSFoundationVersionNumber> = NSFoundationVersionNumber_iOS_6_1){}
Joel Balmer

26

解决方案:

通过覆盖方法在您的viewcontroller或rootviewcontroller中进行设置:

-(BOOL) prefersStatusBarHidden
    {
        return YES;
    }

不错的解决方案。完全卸下杆。并非一直都是UX的理想之选,但可行。
Farhan Hafeez 2013年

就是棒。完美地为我工作。
madLokesh 2013年

场景:全屏播放视频后,一旦切换回UIVIew,底部会出现一个黑色的栏,其大小与状态栏的大小相同,尽管我已经在使用状态栏。我完全删除了状态栏,现在问题已解决。
madLokesh

我只成功使用了这种方法
user2277872 '02

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,并将your 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的布局。为此,请执行以下操作:

    • 确保Use Autolayout未选中您的Storyboard(这是因为,否则“大小检查器”中不会显示“ iOS 6/7 Deltas”)。去做这个:
      • 选择您的情节提要文件
      • 显示实用程序
      • 选择“显示文件检查器”
      • 在“ Interface Builder文档”下,取消选中“使用自动版式”
    • (可选)为帮助您在应用时监视iOS 7和6的布局更改,请选择“助手编辑器”,选择“预览”和“ iOS 6.1或更早版本”: 在此处输入图片说明 在此处输入图片说明
    • 现在,选择要调整的UI元素,以使其不再与状态栏重叠
    • 在“实用程序”列中选择“显示尺寸检查器”
    • 将UI元素沿Y轴重新放置与状态栏bg高度相同的量: 在此处输入图片说明
    • 并将Y的iOS6 / 7 Delta值更改为与状态栏bg高度相同的负值(如果使用,请注意iOS 6预览中的更改): 在此处输入图片说明

备择方案:

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

这种替代方法的缺点(尽管考虑到自动旋转兼容性可以忽略不计)是,如果您正在查看iOS 6的Storyboard,则无法立即看到该额外视图。只有当您查看“情节提要的“文档大纲”。


12

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

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


7
如果您使用的是故事板,这是唯一可行的
心教堂

3
它仅适用于容器vc,例如导航控制器或标签栏控制器
Andrea

2
edgeForExtendedLayout仅由容器视图控制器(如UINavigationController)用于确定其子视图是否应与父视图的镶边重叠。在根视图控制器上为UIWindow设置此属性不会执行任何操作。见我的回答以上:stackoverflow.com/questions/18294872/...
jaredsinclair

您如何为UITabBarController @Andrea做到这一点?谢谢。
KarenAnne

@KarenAnne取决于您是以编程方式还是使用情节提要。以编程方式,您只需要将edgeForExtent属性设置为在UITabBarViewController内部显示的视图控制器中所需的属性,但是要解决状态栏问题,您必须在UITabbarController内部加载uinavigationcontroller。在这里检查。developer.apple.com/library/ios/documentation/UserExperience/...
安德烈

11

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


5
苹果公司假设每个人都在使用自动布局。自动布局在Xcode 4中非常可怕,而Xcode 5才刚刚发布,因此这是一个可疑的假设。
格伦·梅纳德

1
但是在前景上,这是一个比根窗口或状态栏的大小调整更好的解决方案。
伊戈尔

据我所知,如果您的rootViewController是splitViewController,Apple的解决方案将无法正常工作。
维尔恩·詹森

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

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


2
我应该在哪里添加?在应用程序委托中启动了选项吗?
mhmdshawqi 2013年

当我这样做时,我的状态栏变成白色
ropo 2014年

6

这是Archy Holt的答案的一个小替代方案,简单一些:

一个。设置UIViewControllerBasedStatusBarAppearanceNOinfo.plist

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:有疑问吗?
顿Đỗ2013年

@TùngĐỗ真实的,所以我做了一个替代方案,工作得更好:stackoverflow.com/questions/18294872/...
心教堂

5

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

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

    [super viewDidLoad];
}

1
像魅力一样工作,而且容易死。在红宝石运动中,在调用超级方法之前:self.edgesForExtendedLayout = UIRectEdgeNone if responsesToSelector(“ edgesForExtendedLayout”)
tehprofessor

4

试试这个简单的方法。

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


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

更好的方法是使UINavigationBar height等于64而不是44。然后,栏会一直延伸到顶部,就像Apple的应用程序一样。
亚伦·布拉格2013年

@AaronBrager但是我的要求是显示iOS 6样式状态栏。
沙漠玫瑰

您能否添加适用于iOS的Landscape Orientation的解决方案?我在做同样的事情。但在iOS 7 Landscape中不起作用。
sathiamoorthy

@DesertRose THX!这对我有用,但它切断了底部的uitabbar。我有一个基于标签栏控制器的应用程序,具有3个视图,其中2个是tableviewcontrollers。
marciokoko

1
直到我旋转设备(我的iOS 7设备是iPad),此设备才能完美修复。但是一旦旋转,黑条便会保持原样,并且“视图”(抱歉,如果使用的是错误的技术术语,我是PhoneGap /网络专家)将保持其缩小的高度-不再是该高度,而是宽度。该解决方案不支持旋转,但是这是我所见过的最好的解决方法-如何改进它以监视设备旋转?谢谢!
tylerl

2

如果您正在使用“界面”构建器,请尝试以下操作:

在您的xib文件中:

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

2)确保背景是一个独立的子视图,该子视图位于控制器视图的顶级子级中。
移动背景,使其成为控制器视图的直接子级。检查自动调整大小面板,以确保已锁定所有框架边缘,激活了两个柔韧性轴,并且如果这是UIImageView,则将内容模式设置为“缩放以填充”。以编程方式将其转换为contentMode设置为UIViewContentModeScaleToFill,并将其自动调整大小掩码设置为(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)。

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

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

5)最后,锁定到底框而不是顶框的项目完全不需要增量。

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

另一方面,如果在保持iOS6兼容性的同时设置iOS7样式,则可以将背景视图的增量Y /增量高度值设置为0。

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


使用自动版面配置时不会出现任何变化
失落

2

我的解决方案是UIView在iOS 7上在窗口顶部添加一个高度为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]在需要时致电。


2

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

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

+ (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

最简单的方法是将较旧的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

希望对您有帮助。它为我工作=)


为我工作。感谢@marcelosalloum,但仍在为我的phonegap(uiwebview)应用程序寻找一种解决方法,以支持iOS7的透明状态栏,以便将来对我的应用程序进行更新。再次感谢。;)
hanism

@marcellosaloum,您确定该应用程序将被Apple接受吗?他们说,不再使用XCode 4编译的应用程序……事实上,这意味着iOS 6 SDK。
Valerio 2014年

我的应用程序确实被接受,因为Xcode5可以编译较旧的iOS SDK。我不确定AppStore是否会拒绝Xcode4构建的应用程序,但是否像您所说的那样(Xcode4!= iOS 6 SDK)。
marcelosalloum 2014年

是2月1日之后吗?在那一天,Apple强制执行该命令。
Valerio 2014年

不,是去年,最后一次触及该密码的人。不知道苹果已经将其强制执行了(虽然不高兴知道)。您能在这里发布这样的链接吗?干杯
marcelosalloum 2014年

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动画的强大解决方法。


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

0

我的非常简单的解决方案(假设您仅支持垂直方向)是在应用程序委托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];
}

您的代码只是将“ y”从0转换为20,但不会相应地调整高度,因此您应该添加screenBounds.size.height-= 20; 在screenBounds.origin.y = 20之后;
阿米特C.

0

您可以一起隐藏状态栏。因此您的应用将是全屏的。我认为那是最好的。

UIStatusBarStyleNone 或在目标设置中进行设置。


2
在哪里指定UIStatusbarstylenone
2013年

0

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

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

2.AndSet,基于视图控制器的状态栏外观:布尔型NO

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


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


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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.