如何通过编程获得iOS状态栏高度

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

224722 次浏览

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

鉴于这个答案被认为是有帮助的,我应该详细说明。

状态栏高度确实等于20.0f points 除了以下情况:

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

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

还有一个用户界面定向的例子。状态栏不尊重方向值,因此状态栏高度值肖像模式是[UIApplication sharedApplication].statusBarFrame.size.height(是的,默认方向总是纵向,不管你的应用程序信息。plist表示),用于景观 - [UIApplication sharedApplication].statusBarFrame.size.width。当在UIViewControllerself.interfaceOrientation之外不可用时,要确定UI的当前方向,使用[UIApplication sharedApplication].statusBarOrientation

iOS7更新。即使状态栏的视觉风格改变了,它仍然在那里,它的框架仍然表现相同。关于状态栏我唯一有趣的发现-我分享:你的UINavigationBar平铺的背景也将平铺到状态栏,所以你可以实现一些有趣的设计效果或只是颜色你的状态栏。这也不会以任何方式影响状态栏的高度。

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

试试这个:

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

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

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

试试吧,你自己就知道了。将高度硬编码为20pt通常可以工作,直到它不起作用。

所以我赞同H2CO3的答案:

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

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

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

然后你可以直接读取statusBarFrame的height属性。在这个例子中,'View'应该是你希望使用测量值的视图,很可能是应用程序窗口的根视图控制器。

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

使用马丁对这个问题的建议是:获取iPhone状态栏高度

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

在Swift中

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

看起来像黑客,但实际上很结实。不管怎样,这是唯一可行的解决方案。

旧的答案

下面的代码将放在UIViewController的自定义子类中,几乎可以支持横屏。但是,我注意到一个角落的情况下(当旋转从右>不支持颠倒>左),它不起作用(切换高度&宽度)。

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

iOS中默认状态栏高度为20 pt

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

使用以下单行代码,您可以获得状态栏的高度在任何方向,也如果它是可见的或不可见

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

这只是一个简单但非常有用的宏,尝试一下,你不需要写任何额外的代码

<强>编辑 iOS 11的方法来确定在哪里放置你的视图内容的顶部是UIView的safeAreaLayoutGuideUIView文档

< >强弃用的答案 如果你的目标是iOS 7+, UIViewController的文档建议viewController的topLayoutGuide属性给你状态栏的底部,或者导航栏的底部,如果它也是可见的。这可能是有用的,当然不像以前的许多解决方案那么糟糕

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

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

迅速:

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

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

下面是一个快速获取屏幕状态栏高度的方法:

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

这些都是作为标准函数包含在我的项目:https://github.com/goktugyil/EZSwiftExtensions

Swift 3或Swift 4:

UIApplication.shared.statusBarFrame.height

对于iOS 13,你可以使用:

UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height
    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
}

斯威夫特5

UIApplication.shared.statusBarFrame.height

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

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

在iOS 13中,你可以像下面这样检索状态栏高度:

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

NB !这是可选的,所以要确保你有正确的退路。