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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS 7状态栏在iPhone应用程序中恢复到iOS 6默认样式?相关的知识,希望对你有一定的参考价值。

ios 7中,UIStatusBar的设计方式与它的视图合并如下:

(由Tina Tavčar设计的GUI)

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

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

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

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

答案

这是来自a blog post I wrote的交叉发布,但这是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属性。调整edgesForExtendedLayout在大多数情况下不执行任何操作。 UIKit使用此属性的唯一方法是,如果将视图控制器添加到UINavigationController,则UINavigationController使用edgesForExtendedLayout来确定其子视图控制器是否应在导航栏/状态栏区域下可见。在UINavigationController上设置edgesForExtendedLayout本身不会改变UINavigationController是否具有44或64点高导航栏区域。有关该逻辑,请参阅#4。使用工具栏或UITabBarController时,类似的布局逻辑适用于视图的底部。
  7. 如果你想要做的就是阻止你的自定义子视图控制器在UINavigationController内部使用导航栏,那么将edgesForExtendedLayout设置为UIRectEdgeNone(或者至少是一个排除UIRectEdgeTop的掩码)。在视图控制器的生命周期中尽早设置此值。
  8. UINavigationController和UITabBarController还将尝试在其子视图层次结构中填充表视图和集合视图的contentInsets。它以类似于#4的状态栏逻辑的方式执行此操作。通过为表视图和集合视图设置automaticAdjustsScrollViewInsets为NO(默认为YES),有一种编程方法可以防止这种情况。这给Whisper和Riposte带来了一些严重的问题,因为我们使用contentInset调整来控制表视图的布局以响应工具栏和键盘的移动。
  9. 重申:没有办法返回iOS 6样式状态栏布局逻辑。为了估算这一点,您必须将应用程序的所有视图控制器移动到距离屏幕顶部偏移20点的容器视图中,在状态栏后面留下有意黑色视图以模拟旧外观。这是我们最终在Riposte和Whisper中使用的方法。
  10. Apple非常努力地确保你不要尝试#9。他们希望我们重新设计我们的所有应用程序以覆盖状态栏。然而,对于用户体验和技术原因,有许多有说服力的论据,为什么这并不总是一个好主意。您应该为用户做最好的事情而不是简单地遵循平台的奇思妙想。
另一答案

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

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

    [super viewDidLoad];
}
另一答案

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

第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];
    }
另一答案

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

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

另一答案

我已经在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"];
另一答案

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

在你的xib文件中:

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

2)确保背景是一个自包含的子视图,定位为控制器视图的顶级子视图。 移动背景以成为控制器视图的直接子项。检查自动调整面板以确保已锁定所有框架边缘,激活两个灵活性轴,如果这是UIImageView,请将内容模式设置为“缩放以填充”。以编程方式,这将转换为设置为UIViewContentModeScaleToFill的contentMode,并将其自动调整大小掩码设置为(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中相同的状态栏。

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

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

另一答案

我的解决方案是在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]

另一答案

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

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

+ (void)addStatusBarIfiOS7:(UIViewController *)vc
    {
     

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

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

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

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

iOS-导航栏、状态栏及Tabbar高度(区分iPhone X与其他iPhone机型)

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

在 iOS 7 中,导航栏在运行时不可见