更新我的iOS7应用程序时,UI显示在状态栏区域内。请参阅下面的图片中的“关于我们”和搜索按钮。
在iOS6中,它从状态栏下方的正确位置开始。请注意,我是以编程方式创建此UI,而不是从故事板创建。
我找到了以下解决方案并将其放在我的视图控制器中,但它无法正常工作:
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
{
self.edgesForExtendedLayout = UIRectEdgeNone;
}
我的rootViewController
是标签栏,我也尝试了以下运气:
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
{
self.tabBarController.edgesForExtendedLayout = UIRectEdgeNone;
}
在我的其他故事板应用程序中,我能够在底栏和顶栏下取消选择。如果没有故事板,我该怎么做才能达到同样的效果?
答案 0 :(得分:23)
这是a blog post I wrote的交叉发布,但这是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的容易混淆的edgesForExtendedLayout属性。调整edgesForExtendedLayout在大多数情况下不执行任何操作。 UIKit使用此属性的唯一方法是,如果将视图控制器添加到UINavigationController,则UINavigationController使用edgesForExtendedLayout来确定其子视图控制器是否应在导航栏/状态栏区域下可见。在UINavigationController上设置edgesForExtendedLayout本身不会改变UINavigationController是否具有44或64点高导航栏区域。有关该逻辑,请参阅#4。使用工具栏或UITabBarController时,类似的布局逻辑适用于视图的底部。
如果你想要做的就是阻止你的自定义子视图控制器在UINavigationController内置于导航栏下面,然后将edgesForExtendedLayout设置为UIRectEdgeNone(或者至少是一个排除UIRectEdgeTop的掩码)。在视图控制器的生命周期中尽早设置此值。
UINavigationController和UITabBarController还将尝试在其子视图层次结构中填充表视图和集合视图的contentInsets。它以类似于#4的状态栏逻辑的方式执行此操作。通过为表视图和集合视图设置automaticAdjustsScrollViewInsets为NO(默认为YES),有一种编程方法可以防止这种情况。这给Whisper和Riposte带来了一些严重的问题,因为我们使用contentInset调整来控制表视图的布局以响应工具栏和键盘的移动。
重申:无法返回iOS 6样式状态栏布局逻辑。为了近似这一点,您必须将应用程序的所有视图控制器移动到距离屏幕顶部偏移20点的容器视图中,在状态栏后面留下有意黑色视图以模拟旧外观。这是我们最终在Riposte和Whisper中使用的方法。
Apple正在努力确保您不要尝试#9。他们希望我们重新设计我们的所有应用程序以覆盖状态栏。然而,对于用户体验和技术原因,有许多有说服力的论据,为什么这并不总是一个好主意。您应该为用户做最好的事情而不是简单地遵循平台的奇思妙想。
答案 1 :(得分:3)
在检查了哪个OS用户正在使用之后,只需将此行添加到AppDelegate。
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-20);
self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);
}
答案 2 :(得分:2)
我希望这会对你有所帮助。此代码适用于我。请将此代码粘贴到ViewDidLoad
中 if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
答案 3 :(得分:1)
对于IOS7,您的状态栏高度从顶部开始,默认情况下是IOS6。
float SystemVersion=[[[UIDevice currentDevice] systemVersion] floatValue];
if(SystemVersion<7.0f)
{
//Currently your app is running in IOS6 or older version. So you need not to do anything.
}
else
{
// Currently your app is running in IOS7. Do the following.
CGRect TempRect;
for(UIView *sub in [[self view] subviews])
{
TempRect=[sub frame];
TempRect.origin.y+=20.0f; //Height of status bar
[sub setFrame:TempRect];
}
}