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

leh*_*058 272 uikit ios retina-display

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

Kyr*_*off 500

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

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

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

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

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

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

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

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

  • 不完全:通话期间状态栏高度为40点. (72认同)
  • 这个方法产生1024(iOS7) (6认同)
  • 另外在iPhone X状态栏上会更高. (5认同)
  • 是的,正如Marc在iOS7上指出的那样,它有时会发生1024次,有时会发生20次.所以这不再是确定高度的万无一失的方法.我怀疑这是因为iOS 7状态栏的透明性.可能是,它首先进入全屏,然后自行调整大小.因此,如果您在此转换期间进行应用查询,则可能会得到错误的值.可能会延迟调用此方法可能有助于iOS 7. (2认同)
  • @pre 是的,iPhone X 使用 44。 (2认同)

ma1*_*w28 98

按照马丁对这个问题的建议:获取iPhone状态栏高度.

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

在斯威夫特

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

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

老答案

以下代码将在您的自定义子类中进行UIViewController,几乎可以支持格局.但是,我注意到一个角落的情况(从右侧旋转>不支持倒置>左侧),它不起作用(切换高度和宽度).

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

  • @ lehn0058这不是一个bug,而是Apple内部处理这个问题的方式.它附加到窗口,并使用变换旋转该窗口.`statusBarFrame`作为变换前的值返回. (2认同)

小智 23

试试这个:

CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
Run Code Online (Sandbox Code Playgroud)


Wil*_*son 18

Swift 3或Swift 4:

UIApplication.shared.statusBarFrame.height
Run Code Online (Sandbox Code Playgroud)


Mac*_*tle 10

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

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

试试吧,你会亲眼看到.将高度硬编码到20pt通常会起作用,直到它没有.

所以我第二个H2CO3的答案:

statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
Run Code Online (Sandbox Code Playgroud)


Jos*_*non 9

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

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


小智 8

对于 iOS 13,您可以使用:

UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height
Run Code Online (Sandbox Code Playgroud)


Ash*_*Ash 5

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

CGRect statusBarFrame = [self.window convertRect:[UIApplication sharedApplication].statusBarFrame toView:view];
Run Code Online (Sandbox Code Playgroud)

然后,您可以直接读取statusBarFrame的height属性.此实例中的"视图"应该是您希望使用测量的视图,很可能是应用程序窗口的根视图控制器.

顺便提一下,不仅状态栏在电话呼叫期间可能更高,如果故意隐藏状态栏,它也可以为零.