如何以编程方式获取 iOS 状态栏高度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12991935/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:51:08  来源:igfitidea点击:

How to programmatically get iOS status bar height

iosuikitretina-display

提问by lehn0058

I know that currently the status bar (with the time, battery, and network connection) at the top of the iPhone/iPad is 20 pixels for non-retina screens and 40 pixels for retina screens, but to future proof my app I would like to be able to determine this without hard coding values. Is it possible to figure out the height of the status bar programmatically?

我知道目前 iPhone/iPad 顶部的状态栏(带有时间、电池和网络连接)对于非视网膜屏幕是 20 像素,对于视网膜屏幕是 40 像素,但为了将来证明我的应用程序我想要能够在没有硬编码值的情况下确定这一点。是否可以以编程方式计算出状态栏的高度?

回答by Kyr Dunenkoff

[UIApplication sharedApplication].statusBarFrame.size.height. But since all sizes are in points, not in pixels, status bar height always equals 20.

[UIApplication sharedApplication].statusBarFrame.size.height. 但由于所有大小都是以磅为单位,而不是像素,因此状态栏高度始终等于 20。

Update.Seeing this answer being considered helpful, I should elaborate.

更新。看到这个答案被认为有帮助,我应该详细说明。

Status bar height is, indeed, equals 20.0f points exceptfollowing cases:

以下情况,状态栏高度实际上等于 20.0f 点:

  • status bar has been hidden with setStatusBarHidden:withAnimation:method and its height equals 0.0f points;
  • as @Anton here pointed out, during an incoming call outside of Phone application or during sound recording session status bar height equals 40.0f points.
  • 状态栏已被setStatusBarHidden:withAnimation:方法隐藏,其高度等于 0.0f 点;
  • 正如@Anton 在这里指出的那样,在电话应用程序之外的来电期间或在录音会话期间状态栏高度等于 40.0f 点。

There's also a case of status bar affecting the height of your view. Normally, the view's height equals screen dimension for given orientation minus status bar height. However, if you animate status bar (show or hide it) after the view was shown, status bar will change its frame, but the view will not, you'll have to manually resize the view after status bar animation (or during animation since status bar height sets to final value at the start of animation).

还有一种状态栏会影响视图高度的情况。通常,视图的高度等于给定方向的屏幕尺寸减去状态栏高度。但是,如果您在显示视图后动画状态栏(显示或隐藏它),状态栏将更改其框架,但视图不会,您必须在状态栏动画后(或在动画期间)手动调整视图大小,因为状态栏高度设置为动画开始时的最终值)。

Update 2.There's also a case of user interface orientation. Status bar does not respect the orientation value, thus status bar height value for portraitmode is [UIApplication sharedApplication].statusBarFrame.size.height(yes, default orientation is always portrait, no matter what your app info.plist says), for landscape- [UIApplication sharedApplication].statusBarFrame.size.width. To determine UI's current orientation when outside of UIViewControllerand self.interfaceOrientationis not available, use [UIApplication sharedApplication].statusBarOrientation.

更新 2.还有一个用户界面方向的情况。状态栏不尊重方向值,因此纵向模式的状态栏高度值是[UIApplication sharedApplication].statusBarFrame.size.height(是的,默认方向始终是纵向,无论您的应用 info.plist 说什么),对于横向- [UIApplication sharedApplication].statusBarFrame.size.width。要在外部UIViewControllerself.interfaceOrientation不可用时确定 UI 的当前方向,请使用[UIApplication sharedApplication].statusBarOrientation.

Update for iOS7.Even though status bar visual style changed, it's still there, its frame still behaves the same. The only interesting find about status bar I got –?I share: your UINavigationBar's tiledbackground will also be tiled to status bar, so you can achieve some interesting design effects or just color your status bar. This, too, won't affect status bar height in any way.

iOS7 更新。即使状态栏的视觉风格改变了,它仍然存在,它的框架仍然表现得一样。我得到的唯一一个关于状态栏的有趣发现——?我分享:你UINavigationBar平铺背景也将平铺到状态栏,因此您可以实现一些有趣的设计效果或只是为状态栏着色。这也不会以任何方式影响状态栏高度。

Navigation bar tiled background is also tiled to status bar

导航栏平铺背景也平铺到状态栏

回答by ma11hew28

Go with Martin's suggestion to the question: Get iPhone Status Bar Height.

按照Martin 对问题的建议: Get iPhone Status Bar Height

CGFloat AACStatusBarHeight()
{
    CGSize statusBarSize = [[UIApplication sharedApplication] statusBarFrame].size;
    return MIN(statusBarSize.width, statusBarSize.height);
}

And in Swift

而在斯威夫特

func statusBarHeight() -> CGFloat {
    let statusBarSize = UIApplication.shared.statusBarFrame.size
    return Swift.min(statusBarSize.width, statusBarSize.height)
}

It seems like a hack, but it's actually pretty solid. Anyway, it's the only working solution.

这看起来像一个黑客,但它实际上非常可靠。无论如何,这是唯一可行的解​​决方案。

Old Answer

旧答案

The following code, which would go in your custom subclass of UIViewController, almost worked to support landscape. But, I noticed a corner case (when rotating from right > unsupported upside-down > left) for which it didn't work (switched height & width).

以下代码将包含在 的自定义子类中UIViewController,几乎可以支持横向。但是,我注意到一个角落案例(从右侧旋转时>不受支持的倒置>左侧)它不起作用(切换高度和宽度)。

BOOL isPortrait = self.interfaceOrientation == UIInterfaceOrientationPortrait;
CGSize statusBarSize = [UIApplication sharedApplication].statusBarFrame.size;
CGFloat statusBarHeight = (isPortrait ? statusBarSize.height : statusBarSize.width);

回答by ma11hew28

Try this:

尝试这个:

CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;

回答by Wilson

Swift 3 or Swift 4:

斯威夫特 3 或斯威夫特 4:

UIApplication.shared.statusBarFrame.height

回答by Macondo2Seattle

While the status bar is usually 20pt tall, it can be twice that amount in some situations:

虽然状态栏通常是 20pt 高,但在某些情况下它可能是两倍高:

  • when you're in the middle of a phone call (that's a pretty common scenario);
  • when the voice recorder, or Skype, or a similar app, is using the microphone in the background;
  • when Personal Hotspot is activated;
  • 当你在打电话时(这是一个很常见的场景);
  • 当录音机、Skype 或类似应用程序在后台使用麦克风时;
  • 当个人热点被激活时;

Just try it, and you'll see for yourself. Hardcoding the height to 20pt will usually work, until it doesn't.

只要尝试一下,你就会亲眼看到。将高度硬编码为 20pt 通常会起作用,直到它不起作用。

So I second H2CO3's answer:

所以我第二个 H2CO3 的回答:

statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;

回答by Joshua J. McKinnon

EDITThe iOS 11 way to work out where to put the top of your view content is UIView's safeAreaLayoutGuideSee UIView Documentation.

编辑iOS 11 计算视图内容顶部位置的方法是 UIView 的safeAreaLayoutGuideSee UIView Documentation

DEPRECATED ANSWERIf you're targeting iOS 7+, The documentation for UIViewController advises that the viewController's topLayoutGuideproperty gives you the bottom of the status bar, or the bottom of the navigation bar, if it's also visible. That may be of use, and is certainly less hack than many of the previous solutions.

已弃用的答案如果您的目标是 iOS 7+,则 UIViewController 的文档建议 viewController 的topLayoutGuide属性为您提供状态栏的底部或导航栏的底部(如果它也可见)。这可能很有用,而且肯定比以前的许多解决方案都少。

回答by Ash

Don't forget that the status bar's frame will be in the screen's coordinate space! If you launch in landscape mode, you may find that width and height are swapped. I strongly recommend that you use this version of the code instead if you support landscape orientations:

不要忘记状态栏的框架将在屏幕的坐标空间中!如果您以横向模式启动,您可能会发现宽度和高度互换了。如果您支持横向,我强烈建议您改用此版本的代码:

CGRect statusBarFrame = [self.window convertRect:[UIApplication sharedApplication].statusBarFrame toView:view];

You can then read statusBarFrame's height property directly. 'View' in this instance should be the view in which you wish to make use of the measurements, most likely the application window's root view controller.

然后您可以直接读取 statusBarFrame 的高度属性。在这种情况下,“视图”应该是您希望使用测量值的视图,很可能是应用程序窗口的根视图控制器。

Incidentally, not only may the status bar be taller during phone calls, it can also be zero if the status bar has been deliberately hidden.

顺便说一句,不仅在通话时状态栏可能会更高,如果状态栏被故意隐藏,它也可能为零。

回答by Eugene Lezov

For iOS 13 you can use:

对于 iOS 13,您可以使用:

UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height

回答by Esqarrouth

Here is a Swift way to get screen status bar height:

这是获取屏幕状态栏高度的 Swift 方法:

var screenStatusBarHeight: CGFloat {
    return UIApplication.sharedApplication().statusBarFrame.height
}

These are included as a standard function in a project of mine: https://github.com/goktugyil/EZSwiftExtensions

这些在我的项目中作为标准功能包含在内:https: //github.com/goktugyil/EZSwiftExtensions

回答by Bassant Ashraf

    var statusHeight: CGFloat!
    if #available(iOS 13.0, *) {
         statusHeight = UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height
    } else {
        // Fallback on earlier versions
        statusHeight = UIApplication.shared.statusBarFrame.height
    }