iOS 7 状态栏在 iPhone 应用程序中回到 iOS 6 默认样式? [英] iOS 7 status bar back to iOS 6 default style in iPhone app?

查看:26
本文介绍了iOS 7 状态栏在 iPhone 应用程序中回到 iOS 6 默认样式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 iOS 7 中,UIStatusBar 的设计方式使其与视图合并,如下所示:

In iOS 7 the UIStatusBar has been designed in a way that it merges with the view like this:

(由 Tina Tavčar 设计的 GUI)

(GUI designed by Tina Tavčar)

  • 这很酷,但是当你的视图顶部有东西时它会有点混乱你的视图,并且它会与状态栏重叠.

  • It is cool, but it will somewhat mess up your view when you have something at the top part of your view, and it becomes overlapped with the status bar.

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

Is there a simple solution (such as setting a property in info.plist) that can change the way it works [not overlapping] back to how it is in iOS6?

我知道一个更直接的解决方案是为每个视图控制器设置 self.view.center.x + 20 个点,但是更改它们会搞砸其他维度(具有不同的self.view.center.x 可能会导致自定义 segue 等问题),突然间它变成了一项最好避免的乏味工作.

I know a more straightforward solution is to have self.view.center.x + 20 points for every single view controller, but changing them will screw other dimensions up (having a different self.view.center.x can cause problem to custom segues, etc.) and suddenly it turns into a tedious job that is best to be avoided.

如果有人可以为此提供一个单一的解决方案,我将非常高兴.

I'll really be glad if someone can provide me an one-liner solution for this.

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

P.S. I know I can hide the status bar by doing things like having

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

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

In didFinishLaunchingWithOptions method, but that's a workaround, a shortcut avoiding the problem, so I don't consider that a real solution.

推荐答案

这是交叉发布自 我写的一篇博文,但这里是 iOS 7 上状态栏、导航栏和容器视图控制器的完整概要:

This is cross-posted from a blog post I wrote, but here is the full rundown on status bars, navigation bars, and container view controllers on iOS 7:

  1. 没有办法保留 iOS 6 风格的状态栏布局.在 iOS 7 上,状态栏将始终与您的应用重叠

  1. There is no way to preserve the iOS 6 style status bar layout. The status bar will always overlap your application on iOS 7

不要将状态栏外观与状态栏布局混淆.外观(浅色或默认)不会影响状态栏的布局方式(框架/高度/重叠).还需要注意的是,系统状态栏不再有任何背景颜色.当 API 引用 UIStatusBarStyleLightContent 时,它们表示清晰背景上的白色文本.UIStatusBarStyleDefault 是清晰背景上的黑色文本.

Do not confuse status bar appearance with status bar layout. The appearance (light or default) does not affect how the status bar is laid out (frame/height/overlap). It is important to note as well that the system status bar no longer has any background color. When the API refers to UIStatusBarStyleLightContent, they mean white text on a clear background. UIStatusBarStyleDefault is black text on a clear background.

状态栏外观由两个互斥的基础路径之一控制:您可以以传统方式以编程方式设置它们,或者 UIKit 将根据 UIViewController 的一些新属性为您更新外观.后一个选项默认开启.检查您应用的 plist 值是否为基于 ViewController 的状态栏外观",以查看您使用的是哪一个.如果将此值设置为 YES,则应用程序中的每个顶级视图控制器(标准 UIKit 容器视图控制器除外)都需要覆盖 PreferredStatusBarStyle,返回默认样式或灯光样式.如果将 plist 值编辑为 NO,则可以使用熟悉的 UIApplication 方法管理状态栏外观.

Status bar appearance is controlled along one of two mutually-exclusive basis paths: you can either set them programmatically in the traditional manner, or UIKit will update the appearance for you based on some new properties of UIViewController. The latter option is on by default. Check your app’s plist value for "ViewController-Based Status Bar Appearance" to see which one you’re using. If you set this value to YES, every top-level view controller in your app (other than a standard UIKit container view controller) needs to override preferredStatusBarStyle, returning either the default or the light style. If you edit the plist value to NO, then you can manage the status bar appearance using the familiar UIApplication methods.

UINavigationController 将根据一组相当奇怪且未记录的约束将其 UINavigationBar 的高度更改为 44 点或 64 点.如果 UINavigationController 检测到其视图框架的顶部与其 UIWindow 的顶部在视觉上是连续的,则它会绘制高度为 64 磅的导航栏.如果其视图的顶部与 UIWindow 的顶部不连续(即使仅相差一个点),则它以传统"方式绘制其导航栏,高度为 44 点.此逻辑由 UINavigationController 执行,即使它是应用程序的视图控制器层次结构中的多个子级.没有办法阻止这种行为.

UINavigationController will alter the height of its UINavigationBar to either 44 points or 64 points, depending on a rather strange and undocumented set of constraints. If the UINavigationController detects that the top of its view’s frame is visually contiguous with its UIWindow’s top, then it draws its navigation bar with a height of 64 points. If its view’s top is not contiguous with the UIWindow’s top (even if off by only one point), then it draws its navigation bar in the "traditional" way with a height of 44 points. This logic is performed by UINavigationController even if it is several children down inside the view controller hierarchy of your application. There is no way to prevent this behavior.

如果您提供的自定义导航栏背景图像只有 44 点(88 像素)高,并且 UINavigationController 的视图边界与 UIWindow 的边界匹配(如 #4 中所述),则 UINavigationController 会将您的图像绘制到框架(0,20,320,44),在您的自定义图像上方留下 20 个不透明的黑色空间点.这可能会让您误以为自己是绕过规则 1 的聪明开发人员,但您错了.导航栏仍然是 64 点高.将 UINavigationController 嵌入到幻灯片显示样式的视图层次结构中可以使这一点非常清晰.

If you supply a custom navigation bar background image that is only 44 points (88 pixels) tall, and the UINavigationController’s view’s bounds matches the UIWindow’s bounds (as discussed in #4), the UINavigationController will draw your image in the frame (0,20,320,44), leaving 20 points of opaque black space above your custom image. This may confuse you into thinking you are a clever developer who bypassed rule #1, but you are mistaken. The navigation bar is still 64 points tall. Embedding a UINavigationController in a slide-to-reveal style view hierarchy makes this abundantly clear.

当心 UIViewController 名称混淆的 edgesForExtendedLayout 属性.在大多数情况下,调整 edgeForExtendedLayout 没有任何作用.UIKit 使用此属性的唯一方法是,如果您将视图控制器添加到 UINavigationController,则 UINavigationController 使用 edgesForExtendedLayout 来确定其子视图控制器是否应该在导航栏/状态栏区域下方可见.在 UINavigationController 本身上设置 edgesForExtendedLayout 不会改变 UINavigationController 是否具有 44 点或 64 点高的导航栏区域.有关该逻辑,请参见#4.使用工具栏或 UITabBarController 时,类似的布局逻辑适用于视图底部.

Beware of the confusingly-named edgesForExtendedLayout property of UIViewController. Adjusting edgesForExtendedLayout does nothing in most cases. The only way UIKit uses this property is if you add a view controller to a UINavigationController, then the UINavigationController uses edgesForExtendedLayout to determine whether or not its child view controller should be visible underneath the navigation bar / status bar area. Setting edgesForExtendedLayout on the UINavigationController itself does nothing to alter whether or not the UINavigationController has a 44 or 64 point high navigation bar area. See #4 for that logic. Similar layout logic applies to the bottom of your view when using a toolbar or UITabBarController.

如果您想要做的只是防止您的自定义子视图控制器在 UINavigationController 内覆盖导航栏,则将 edgesForExtendedLayout 设置为 UIRectEdgeNone(或至少一个不包括 UIRectEdgeTop 的掩码).在视图控制器的生命周期中尽早设置此值.

If all you are trying to do is prevent your custom child view controller from underlapping the navigation bar when inside a UINavigationController, then set edgesForExtendedLayout to UIRectEdgeNone (or at least a mask that excludes UIRectEdgeTop). Set this value as early as possible in the life cycle of your view controller.

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

UINavigationController and UITabBarController will also try to pad the contentInsets of table views and collection views in its subview hierarchy. It does this in a manner similar to the status bar logic from #4. There is a programmatic way of preventing this, by setting automaticallyAdjustsScrollViewInsets to NO for your table views and collection views (it defaults to YES). This posed some serious problems for Whisper and Riposte, since we use contentInset adjustments to control the layout of table views in response to toolbar and keyboard movements.

重申:没有办法回到 iOS 6 风格的状态栏布局逻辑.为了近似这一点,您必须将应用程序的所有视图控制器移动到从屏幕顶部偏移 20 个点的容器视图中,在状态栏后面故意留下黑色视图以模拟旧外观.这是我们最终在 Riposte 和 Whisper 中使用的方法.

To reiterate: there is no way to return to iOS 6 style status bar layout logic. In order to approximate this, you have to move all the view controllers of your app into a container view that is offset by 20 points from the top of the screen, leaving an intentionally black view behind the status bar to simulate the old appearance. This is the method we ended up using in Riposte and Whisper.

Apple 正在努力确保您不会尝试执行 #9.他们希望我们重新设计所有应用程序以覆盖状态栏.然而,出于用户体验和技术原因,有许多令人信服的论点,为什么这并不总是一个好主意.您应该为您的用户做最好的事情,而不是简单地跟随平台的奇思妙想.

Apple is pushing very hard to ensure that you don’t try to do #9. They want us to redesign all our apps to underlap the status bar. There are many cogent arguments, however, for both user experience and technical reasons, why this is not always a good idea. You should do what is best for your users and not simply follow the whimsy of the platform.

这篇关于iOS 7 状态栏在 iPhone 应用程序中回到 iOS 6 默认样式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆