在iOS 7中,UIStatusBar的设计方式与以下视图合并:


(GUI由TinaTavčar设计)


很酷,但是当您在视图的顶部有一些东西时,它会使您的视图有些混乱,并且会与状态栏重叠。
是否有一个简单的解决方案(例如设置属性)在info.plist中)可以将其工作方式[不重叠]更改回iOS6中的状态?
我知道一个更直接的解决方案是为每个单个视图控制器设置self.view.center.x + 20点,但是更改它们将使其他尺寸变大(具有不同的self.view.center.x可能会导致自定义序列出现问题,等等),然后突然转向成为最好避免的单调乏味的工作。
如果有人能为我提供一线解决方案,我将感到非常高兴。

P.S.我知道我可以通过执行以下操作来隐藏状态栏:

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


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

评论

不幸的是,ios 7中不赞成使用黑色状态栏。

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

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

将UIStatusBar设置为默认状态栏只会使其内容变为黑色。它不会恢复到iOS 6的功能。

有运气吗?我爱iOS7,但是这件事让我发疯了!

#1 楼

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


保留iOS 6样式状态栏的布局。状态栏将始终在iOS 7上与您的应用程序重叠。
不要将状态栏外观与状态栏布局混淆。外观(浅色或默认)不会影响状态栏的布局方式(帧/高度/重叠)。同样重要的是要注意,系统状态栏不再具有任何背景色。当API引用UIStatusBarStyleLightContent时,它们表示在透明背景上的白色文本。 UIStatusBarStyleDefault是透明背景上的黑色文本。
状态栏外观是通过两个互斥的基本路径之一控制的:您可以以传统方式以编程方式设置它们,或者UIKit将根据某些方式为您更新外观UIViewController的新属性。默认情况下,后一个选项处于启用状态。检查应用程序的“基于ViewController的状态栏外观”的plist值,以查看您使用的是哪个。如果将此值设置为YES,则应用中的每个顶级视图控制器(标准UIKit容器视图控制器除外)都需要覆盖preferredStatusBarStyle,以返回默认样式或浅色样式。如果将plist值编辑为NO,则可以使用熟悉的UIApplication方法管理状态栏的外观。
UINavigationController会将其UINavigationBar的高度更改为44点或64点,具体取决于一组相当奇怪且未记录的约束。如果UINavigationController检测到其视图框架的顶部与UIWindow的顶部在视觉上是连续的,则它将绘制高度为64点的导航栏。如果其视图的顶部与UIWindow的顶部不连续(即使仅偏离一点),则它以“传统”方式绘制其导航栏,高度为44磅。此逻辑由UINavigationController执行,即使它在应用程序的视图控制器层次结构中位于多个子级之下。无法避免这种情况。
如果您提供的自定义导航栏背景图像只有44点(88像素)高,并且UINavigationController的视图范围与UIWindow的范围相匹配(如#4所述), UINavigationController会在帧(0,20,320,44)中绘制您的图像,在您的自定义图像上方留出20点的不透明黑色空间。这可能会使您误以为您是一个聪明的开发人员,绕过了规则#1,但是您却弄错了。导航栏仍高64点。将UINavigationController嵌入到幻灯片显示样式的视图层次结构中可以使这一点变得很清楚。
注意UIViewController的容易混淆的edgeForExtendedLayout属性。在大多数情况下,调整edgeForExtendedLayout不会执行任何操作。 UIKit使用此属性的唯一方法是,如果将视图控制器添加到UINavigationController,则UINavigationController使用edgeForExtendedLayout来确定其子视图控制器在导航栏/状态栏区域下方是否可见。在UINavigationController自身上设置edgeForExtendedLayout不会改变UINavigationController是否具有44或64点高的导航栏区域。有关该逻辑,请参见#4。使用工具栏或UITabBarController时,类似的布局逻辑也适用于视图的底部。
如果要执行的所有操作是防止自定义子视图控制器在UINavigationController内时不覆盖导航栏,则将edgeForExtendedLayout设置为UIRectEdgeNone (或至少一个不包含UIRectEdgeTop的蒙版)。在视图控制器的生命周期中尽早设置此值。
UINavigationController和UITabBarController还将尝试在其子视图层次结构中填充表视图和集合视图的contentInsets。它以类似于#4中状态栏逻辑的方式执行此操作。通过将表视图和集合视图的AutomaticAdjustsScrollViewInsets设置为NO(默认为YES),可以通过编程的方式来防止这种情况。这给Whisper和Riposte带来了一些严重的问题,因为我们使用contentInset调整来控制表视图的布局以响应工具栏和键盘的移动。
重申一下:无法返回到iOS 6样式状态栏布局逻辑。为了对此进行近似,您必须将应用程序的所有视图控制器移到一个容器视图中,该容器视图与屏幕顶部偏移20个点,在状态栏后面故意留出黑色视图以模拟旧外观。这就是我们最终在Riposte和Whisper中使用的方法。
Apple一直在努力确保您不要尝试#9。他们希望我们重新设计所有应用程序以隐藏状态栏。但是,出于用户体验和技术原因,有许多令人信服的论点,为什么这并不总是一个好主意。您应该做最适合您的用户的事情,而不仅仅是遵循平台的异想天开。


评论


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

– BreadicalMD
2013年9月25日下午14:59

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

– jaredsinclair
2013年9月26日16:09

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

– BreadicalMD
2013年9月27日在13:29

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

–杰里米
13-10-16在4:26

很好的答案...但我有一个疑问:1)UINavigationController更改了高度部分。请进一步解释。谢谢

–user1010819
13-10-31在16:12



#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的形式,这是我想出的最短的方法:


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





为了:


检查它是否为iOS7。
将状态栏的内容设置为白色,而不是UIStatusBarStyleDefault。
避免显示其框架超出可见范围的子视图(对于从顶部动画到主视图的视图)。
创建幻想状态栏通过移动和调整应用程序的窗口框架来占用iOS 6中的空间。



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

使用NSNotificationCenter通过添加

检测方向变化在if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)中使用
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidChangeStatusBarOrientation:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];


并在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状态栏错觉。




要更改状态栏的背景色:

添加
AppDelegate.h中使用
 @property (retain, nonatomic) UIWindow *background;


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


不要忘了@synthesize background;之后再问@implementation AppDelegate

评论


旋转中断。只是抬起头

–Jesse Naugher
13年8月26日在19:37

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

–专家
13年8月29日在1:37

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

– Simonbs
2013年9月15日上午8:57

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

– markdorison
2013年9月15日在22:32



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

– KarenAnne
2013年9月26日上午11:38

#3 楼


UPDATE(新解决方案)

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

注意:如果您使用默认的导航控制器,请使用旧的解决方案。
旧解决方案-如果您使用以前的代码,请忽略下面的代码和图像

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


我使用以下代码解决了该问题。这是用于添加状态栏。
didFinishLaunchingWithOptions

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

}


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


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



评论


你过得很愉快,请+1帮助!

– Niru Mukund Shah
2013年9月25日上午11:46

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

–马特
2013年9月26日22:16在

非常感谢!你救了我很多麻烦!

– neowinston
13年10月10日在19:09

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

–Vizllx
13年15月15日上午11:09

好一个!另外,请注意,苹果现在更喜欢这种方式:if(NSFoundationVersionNumber> = NSFoundationVersionNumber_iOS_6_1){}

–乔尔·巴尔默(Joel Balmer)
14年2月16日在22:00

#4 楼

解决方案:

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

-(BOOL) prefersStatusBarHidden
    {
        return YES;
    }


评论


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

–法汉·哈菲兹(Farhan Hafeez)
2013年9月26日18:51



就是棒。完美地为我工作。

–madLokesh
2013年10月16日9:00

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

–madLokesh
13-10-16在9:02



我只成功使用了这种方法

–user2277872
2014年2月3日在16:51

#5 楼

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

GOAL:

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

摘要:

为实现此目的,我们通过移动UI来尽可能多地使用Storyboard。状态栏(在iOS 7下)向下重叠的元素,同时使用增量还原iOS 6.1或更早版本的向下布局更改。然后,在iOS 7中产生的额外空间将由UIView占用,并且backgroundColor设置为我们选择的颜色。后者可以用代码或使用情节提要(请参见下面的替代)创建。

假设:

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

STEPS:



在UIWindow中添加一个子视图到用作状态栏背景。为此,请在application: didFinishLaunchingWithOptions:之后在AppDelegate的makeKeyAndVisible中添加以下内容:




由于以编程方式仅为iOS 7添加了背景,因此您必须进行调整相应地,状态栏重叠的UI元素的布局,同时保留iOS6的布局。为此,请执行以下操作:确保没有为您的情节提要选中Use Autolayout(这是因为否则“大小检查器”中不会显示“ iOS 6/7增量”)。为此,请执行以下操作:


选择情节提要文件
显示实用工具
选择“显示文件检查器”
在“ Interface Builder文档”下,取消选中“使用自动版式“


(可选)为帮助您在应用时监视iOS 7和6的布局更改,请选择“助手编辑器”,选择“预览”和“ iOS 6.1或更早版本”:


现在选择要调整的UI元素,以使其不再与状态栏重叠。
在“实用工具”列中选择“显示尺寸检查器”
将UI元素沿着Y-轴与状态栏bg高度相同的量:


,并将Y的iOS6 / 7 Deltas值更改为与状态栏bg高度相同的负值(请注意iOS 6预览(如果正在使用):





替代品:

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

此替代方法的缺点(尽管考虑到自动旋转,这可以忽略不计)兼容性)的事实是,如果您正在查看iOS 6的Storyboard,则不会立即看到该额外视图。只有查看Storyboard的“文档大纲”,您才会知道它存在。

#6 楼

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



评论


仅在使用情节提要时才有可能

–Cœur
2013年9月13日下午14:58

它仅适用于容器vc,例如导航控制器或Tabbar控制器

– Andrea
2013年9月14日上午9:08

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

– jaredsinclair
2013年9月17日17:12在

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

– KarenAnne
2013年9月26日上午9:52

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

– Andrea
2013年9月26日上午10:33

#7 楼

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

评论


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

– Glenn Maynard
13年10月2日在21:16

但是在前景方面,这是一个比根窗口或状态栏的框架大小更合适的解决方案。

–伊戈尔
13年10月3日,下午5:33

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

–Vern Jensen
13-10-4在19:42

#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状态栏! 〜“〜

评论


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

–mhmdshawqi
2013年12月12日上午8:53

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

–ropo
2014年1月17日15:06

#9 楼

一个比Archy Holt答案更小的选择:

a。在info.plist

b中将UIViewControllerBasedStatusBarAppearance设置为NO。在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Đỗ
2013年9月30日,下午3:58

@TùngĐỗ是,所以我做了一个效果更好的替代方案:stackoverflow.com/questions/18294872/…

–Cœur
13年10月8日在16:48

#10 楼

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

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

    [super viewDidLoad];
}


评论


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

–tehprofessor
13年7月7日在2:18

#11 楼

尝试这种简单的方法。...

步骤1:更改单个viewController

[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque];



步骤2:更改在整个应用中

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



步骤3:还要在每个viewWillAppear中添加它,以调整statusbariOS7高度
    [[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];
    }


#12 楼

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

在Stack Overflow问题中查看一下Interface Builder:UIView的布局是什么? iOS 6/7 Deltas适用于?。

#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方法(如

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

)中分配窗口后,设置windowHeight用户默认值

评论


更好的方法是使UINavigationBar的高度等于64而不是44。然后,栏会一直延伸到顶部,就像Apple的应用程序一样。

–亚伦·布拉格(Aaron Brager)
13-10-3在19:32

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

–沙漠玫瑰
13年10月4日在5:22

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

–sathiamoorthy
13年11月11日在6:48

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

– marciokoko
13年11月18日在21:50

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

– tylerl
2013年12月8日,下午3:21

#14 楼

如果使用的是Interface Builder,请尝试以下操作:

在xib文件中:

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

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

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

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

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

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

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

评论


使用自动版面设计时无变化

–lostintranslation
2014年9月9日20:29在

#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 楼

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

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


#17 楼

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

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


U可以获取可从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。
U现在可以在项目的构建设置中选择一个较旧的SDK。

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

评论


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

–hanism
13-10-8在9:40

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

–Valerio
2014年4月9日在13:44

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

– marcelosalloum
2014年4月9日在14:15

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

–Valerio
2014年4月9日14:37

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

– marcelosalloum
2014年4月9日15:21

#18 楼

由于使用presentViewController:animated:completion:弄乱了window.rootViewController.view,因此我不得不找到解决此问题的另一种方法。我终于通过将rootViewController的UIView子类化了,使其可以使用模态和旋转。

.h

@interface RootView : UIView

@end



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

#19 楼

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

首先->转到您的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;
   }


#20 楼

我的非常简单的解决方案(假设您仅支持垂直方向)是在应用程序委托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。
2014年2月20日在9:07

#21 楼

您可以一起隐藏状态栏。因此,您的应用将为全屏显示。我认为这是您最好的选择。

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

评论


在哪里指定UIStatusbarstylenone

–user4951
13年8月23日在8:30

#22 楼

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

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

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

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

#23 楼

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


#24 楼

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

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

我希望它将清除我们的所有疑问和后顾之忧。

#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