在iOS 7 UIStatusBar中,它的设计方式与视图合并如下:
(由TinaTavčar设计的GUI )
这很酷,但是当你在视图的顶部有一些东西时它会使你的视图陷入混乱,并且它会与状态栏重叠.
是否有一个简单的解决方案(例如在info.plist中设置属性)可以改变它的工作方式[不重叠]回到它在iOS6中的状态?
我知道一个更直接的解决方案是self.view.center.x为每个视图控制器提供+ 20个点,但是更改它们会使其他尺寸self.view.center.x变得更大(有不同可能导致自定义segue等问题)并且突然变成一个单调乏味的工作最好避免.
如果有人能为我提供单线解决方案,我真的很高兴.
PS我知道我可以通过做某事来隐藏状态栏
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
Run Code Online (Sandbox Code Playgroud)
在didFinishLaunchingWithOptions方法中,但这是一个解决方法,一个避免问题的捷径,所以我不认为这是一个真正的解决方案.
jar*_*air 449
这是我写的博客文章的交叉发布,但这是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.他们希望我们重新设计我们的所有应用程序以覆盖状态栏.然而,对于用户体验和技术原因,有许多有说服力的论据,为什么这并不总是一个好主意.您应该为用户做最好的事情而不是简单地遵循平台的奇思妙想.
吖奇说*_*HUō 122
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;
Run Code Online (Sandbox Code Playgroud)为了:
检查它是否是iOS 7.
将状态栏的内容设置为白色,而不是UIStatusBarStyleDefault.
避免其框架超出可见边界的子视图显示(对于从顶部向主视图设置动画的视图).
通过移动和调整应用程序的窗口框架,创建状态栏占用空间的错觉,就像在iOS 6中一样.
使用NSNotificationCenter通过添加来检测方向更改
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidChangeStatusBarOrientation:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
Run Code Online (Sandbox Code Playgroud)
在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);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,当方向发生变化时,它将触发一个switch语句来检测应用程序的屏幕方向(纵向,颠倒,横向左侧或右侧),并分别更改应用程序的窗口框架以创建iOS 6状态栏错觉.
加
@property (retain, nonatomic) UIWindow *background;
Run Code Online (Sandbox Code Playgroud)
在您的类中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];
Run Code Online (Sandbox Code Playgroud)
别忘了@synthesize background;以后@implementation AppDelegate!
İbr*_*lük 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;
}
Run Code Online (Sandbox Code Playgroud)
旧解决方案 - 如果您使用以前的代码,请忽略以下代码和图像
这是旧版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];
}
Run Code Online (Sandbox Code Playgroud)
对于Interface Builder,这适用于使用iOS 6打开的情况; 它从0像素开始.

小智 26
解决方案
通过重写方法在viewcontroller或rootviewcontroller中设置它:
-(BOOL) prefersStatusBarHidden
{
return YES;
}
Run Code Online (Sandbox Code Playgroud)
svr*_*vrs 17
这是另一种广泛使用Storyboard的项目方法:
目标:
这种方法的目标是在iOS7中重新创建与iOS6中相同的状态栏样式(请参阅问题标题"iOS 7 Status Bar返回iOS 6样式?").
摘要:
为了实现这一点,我们通过将状态栏(在iOS 7下)重叠的UI元素向下移动,同时使用增量来恢复iOS 6.1或更早版本的向下布局更改,尽可能多地使用Storyboard.然后,iOS 7中产生的额外空间被UIView占用,backgroundColor设置为我们选择的颜色.后者可以在代码中创建或使用Storyboard创建(参见下面的替代方案)
假设:
为了在按照以下步骤获得所需结果时,假设View controller-based status bar appearance设置为NO并且您Status bar style要么设置为"透明黑色样式(alpha of 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];
}
Run Code Online (Sandbox Code Playgroud)由于您仅以编程方式为iOS 7添加了背景,因此您必须相应地调整与状态栏重叠的UI元素的布局,同时保留其iOS6的布局.要实现此目的,请执行以下操作:
Use Autolayout您的Storyboard未选中(这是因为"尺寸检查器"中未显示"iOS 6/7 Deltas").去做这个:



备择方案:
要在故事板大量项目中添加更少的代码并使状态栏背景自动旋转,而不是以编程方式为状态栏添加背景,您可以为位于所述viewcontroller主视图顶部的每个视图控制器添加彩色视图.然后,您可以将此新视图的高度增量更改为与视图高度相同的负数(以使其在iOS 6下消失).
这个替代方案的缺点(尽管考虑到自动旋转兼容性可能可以忽略不计),如果你正在查看iOS 6的故事板,这个额外的视图不会立即可见.你只会知道它在那里,如果你看看"故事板的"文档大纲".
nvr*_*rst 12
如果您不希望视图控制器与状态栏(和导航栏)重叠,请取消选中Xcode 5 中Interface Builder中的"在顶部栏下扩展边缘"框.

Igo*_*gor 11
Apple发布了技术问答QA1797:防止状态栏覆盖您的观点.它适用于iOS 6和iOS 7版本.
我已经查看了许多很多很多教程来解决这个问题.但它们都不起作用!这是我的解决方案,它适用于我:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
逻辑很简单.我将所有孩子的观点转移到了20个像素的self.view上.就这样.然后,屏幕截图将像iOS 6一样显示.我讨厌iOS7状态栏!〜"〜
Archy Holt答案的一个小替代品,更简单一点:
一个.设置UIViewControllerBasedStatusBarAppearance为NOinfo.plist
湾 在AppDelegate,s application: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];
}
Run Code Online (Sandbox Code Playgroud)
并添加方法:
- (void)applicationDidChangeStatusBarOrientationNotification:(NSNotification *)notification
{
// handling statusBar (iOS7)
self.window.frame = [UIScreen mainScreen].applicationFrame;
}
Run Code Online (Sandbox Code Playgroud)
您还可以考虑子类化UIWindow来处理UIApplicationDidChangeStatusBarOrientationNotification自身.
我在所有的视图控制器中使用它,这很简单.在所有viewDidLoad方法中添加以下行:
- (void)viewDidLoad{
//add this 2 lines:
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
[super viewDidLoad];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
183143 次 |
| 最近记录: |