286

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

4

15 回答 15

517

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

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

状态栏高度确实等于 20.0f 点,以下情况除外:

  • 状态栏已被setStatusBarHidden:withAnimation:方法隐藏,其高度等于 0.0f 个点;
  • 正如@Anton 在这里指出的那样,在电话应用程序之外的来电期间或在录音会话期间状态栏高度等于 40.0f 点。

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

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

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

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

于 2012-10-20T19:36:22.257 回答
102

接受Martin 对问题的建议:Get iPhone Status Bar Height

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

在斯威夫特

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

这似乎是一个 hack,但它实际上非常可靠。无论如何,这是唯一可行的解​​决方案。

旧答案

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

BOOL isPortrait = self.interfaceOrientation == UIInterfaceOrientationPortrait;
CGSize statusBarSize = [UIApplication sharedApplication].statusBarFrame.size;
CGFloat statusBarHeight = (isPortrait ? statusBarSize.height : statusBarSize.width);
于 2013-05-16T22:11:33.287 回答
23

试试这个:

CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
于 2012-10-20T19:36:42.230 回答
21

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

UIApplication.shared.statusBarFrame.height
于 2016-10-19T20:59:03.720 回答
10

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

  • 当您正在打电话时(这是一种很常见的情况);
  • 当录音机、Skype 或类似应用程序在后台使用麦克风时;
  • 当个人热点被激活时;

试试吧,你会亲眼看到的。将高度硬编码为 20pt 通常会起作用,直到它不起作用。

所以我第二次H2CO3的回答:

statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
于 2012-11-28T18:59:20.323 回答
10

编辑 iOS 11 确定视图内容顶部放置位置的方法是 UIView 的safeAreaLayoutGuideSee UIView Documentation

不推荐使用的答案 如果您的目标是 iOS 7+,UIViewController 的文档建议 viewController 的topLayoutGuide属性为您提供状态栏的底部,或者导航栏的底部,如果它也是可见的。这可能是有用的,并且肯定比许多以前的解决方案更少黑客攻击。

于 2014-12-09T02:26:06.577 回答
9

对于 iOS 13,您可以使用:

UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height
于 2019-09-26T08:44:31.063 回答
5

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

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

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

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

于 2013-02-04T17:45:06.740 回答
4
    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
    }
于 2019-11-11T07:59:09.113 回答
2

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

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

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

于 2015-11-24T05:03:08.900 回答
1

UIApplication.shared.statusBarFrame.heightiOS 13中已弃用

'statusBarFrame' 在 iOS 13.0 中已弃用:改用窗口场景的 statusBarManager 属性。

您可以在 iOS 13 中检索状态栏高度,如下所示:

let statusBarHeight = view.window?.windowScene?.statusBarManager?.statusBarFrame.height

注意!它是可选的,因此请确保您有正确的后备。

于 2021-01-28T09:19:15.170 回答
0

默认情况下,iOS 中的状态栏高度为20 pt.

更多信息:http ://www.idev101.com/code/User_Interface/sizes.html

于 2013-10-03T07:49:40.413 回答
0

我刚刚找到了一种方法,允许您不直接访问状态栏高度,而是计算它。

导航栏高度 - topLayoutGuide 长度 = 状态栏高度

迅速:

let statusBarHeight = self.topLayoutGuide.length-self.navigationController?.navigationBar.frame.height

self.topLayoutGuide.length是半透明条覆盖的顶部区域,self.navigationController?.navigationBar.frame.height是不包括状态栏的半透明条,通常为44pt。因此,通过使用这种方法,您可以轻松计算状态栏高度,而无需担心由于电话而导致状态栏高度变化。

于 2015-07-20T20:55:02.933 回答
0

斯威夫特 5

UIApplication.shared.statusBarFrame.height

于 2020-06-17T03:47:46.643 回答
-6

使用以下单行代码,您可以获得任何方向的状态栏高度,以及它是否可见

#define STATUS_BAR_HIGHT (
    [UIApplicationsharedApplication].statusBarHidden ? 0 : (
        [UIApplicationsharedApplication].statusBarFrame.size.height > 100 ?
            [UIApplicationsharedApplication].statusBarFrame.size.width :
            [UIApplicationsharedApplication].statusBarFrame.size.height
    )
)

它只是一个简单但非常有用的宏,只需尝试一下即可,您无需编写任何额外的代码

于 2014-02-11T08:13:57.813 回答