我知道目前iPhone/iPad的状态栏(包括时间、电池和网络连接)在非Retina屏幕上为20像素,在Retina屏幕上为40像素,但为了未来使我的应用更具可靠性,我希望能够在不硬编码数值的情况下确定此高度。是否可能通过编程方式来计算状态栏的高度?
我知道目前iPhone/iPad的状态栏(包括时间、电池和网络连接)在非Retina屏幕上为20像素,在Retina屏幕上为40像素,但为了未来使我的应用更具可靠性,我希望能够在不硬编码数值的情况下确定此高度。是否可能通过编程方式来计算状态栏的高度?
[UIApplication sharedApplication].statusBarFrame.size.height
。但由于所有尺寸都是以点为单位而非像素,状态栏高度始终等于20。
更新:看到这个答案被认为有用,我应该详细说明一下。
状态栏的高度确实等于20.0f点,除了以下情况:
setStatusBarHidden:withAnimation:
方法隐藏状态栏,此时状态栏的高度为0.0f点;还有一种情况是状态栏影响视图的高度。通常,视图的高度等于给定方向的屏幕尺寸减去状态栏高度。但是,如果在视图显示后对状态栏进行动画处理(显示或隐藏),状态栏将更改其框架,但视图不会,您需要在状态栏动画期间手动调整视图大小(或在动画期间进行调整,因为状态栏高度在动画开始时设置为最终值)。
更新2:还有一种用户界面方向的情况。状态栏不遵守方向值,因此纵向模式的状态栏高度值是[UIApplication sharedApplication].statusBarFrame.size.height
(是的,默认方向始终是纵向的,无论您的应用信息.plist说了什么),而横向模式的状态栏高度为[UIApplication sharedApplication].statusBarFrame.size.width
。要在UIViewController
之外确定UI的当前方向并且self.interfaceOrientation
不可用,请使用[UIApplication sharedApplication].statusBarOrientation
。
iOS7更新。即使状态栏的外观样式发生了变化,但它仍然存在,其框架仍然保持相同的行为。我得到的唯一有趣的关于状态栏的发现是:您的UINavigationBar
的tiled背景也将铺设到状态栏,因此您可以实现一些有趣的设计效果或者只是给状态栏上色。这也不会以任何方式影响状态栏高度。
请按照Martin在获取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)
}
看起来像是一个hack,但实际上非常可靠。无论如何,这是唯一有效的解决方案。
以下代码应该放在您的UIViewController
子类中,几乎可以支持横向。但是,我注意到一个特殊情况(从右边旋转>不支持的倒立>左边),它不能工作(切换高度和宽度)。
BOOL isPortrait = self.interfaceOrientation == UIInterfaceOrientationPortrait;
CGSize statusBarSize = [UIApplication sharedApplication].statusBarFrame.size;
CGFloat statusBarHeight = (isPortrait ? statusBarSize.height : statusBarSize.width);
statusBarFrame
返回的是变换之前的值。 - Léo Natanvar statusBarHeight: CGFloat
- Pablo A.试试这个:
CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
Swift 3或Swift 4:
UIApplication.shared.statusBarFrame.height
虽然状态栏通常是20pt高,但在某些情况下可能会增加一倍:
只需尝试一下,您就会看到自己。将高度硬编码为20pt通常有效,但也有例外。
所以我支持H2CO3的答案:
statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
编辑
iOS 11中确定视图内容顶部位置的方法是使用UIView的safeAreaLayoutGuide
。详见UIView文档。
废弃答案
如果你在针对iOS 7及以上版本开发,UIViewController文档建议使用viewController的topLayoutGuide
属性获取状态栏底部或导航栏底部(如果也可见),这可能会有用,而且比之前的许多解决方案更加正式。
对于iOS 13,您可以使用:
UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height
keyWindow
在iOS 13中已被弃用。这从来都不是正确的答案。 - undefined不要忘记状态栏的框架将在屏幕坐标空间中!如果您以横向模式启动,可能会发现宽度和高度被交换了。如果您支持横向方向,请强烈建议您使用此代码版本:
CGRect statusBarFrame = [self.window convertRect:[UIApplication sharedApplication].statusBarFrame toView:view];
UIApplication.shared.statusBarFrame.height
在iOS 13中已被弃用'statusBarFrame'在iOS 13.0中已被弃用:改用窗口场景的statusBarManager属性。
你可以像下面这样在iOS 13中检索状态栏高度:
let statusBarHeight = view.window?.windowScene?.statusBarManager?.statusBarFrame.height
NB!这是可选的,所以请确保你有正确的备用方案。
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
}
keyWindow
。 - undefined