Reputation: 20237
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?
Upvotes: 289
Views: 231402
Reputation: 2997
If you're using UIKit not sure if the same goes for SwiftUI you have access to this variable scene
as you see here in SceneDelegate.swift
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let scene = (scene as? UIWindowScene) else { return }
}
...
}
You can then access the status bar height by:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let scene = (scene as? UIWindowScene) else { return }
// Use this as to your needs.
let height = scene.statusBarManager?.statusBarFrame.height ?? 0
}
...
}
Upvotes: 0
Reputation: 3082
UIApplication.shared.statusBarFrame.height
was deprecated in iOS 13'statusBarFrame' was deprecated in iOS 13.0: Use the statusBarManager property of the window scene instead.
You can retrieve status bar height in iOS 13 like follows:
let statusBarHeight = view.window?.windowScene?.statusBarManager?.statusBarFrame.height
NB! It's optional so make sure you have correct fallback.
Upvotes: 5
Reputation: 1609
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
}
Upvotes: 3
Reputation: 770
For iOS 13 you can use:
UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height
Upvotes: 11
Reputation: 1696
EDIT
The iOS 11 way to work out where to put the top of your view content is UIView's safeAreaLayoutGuide
See UIView Documentation.
DEPRECATED ANSWER
If you're targeting iOS 7+, The documentation for UIViewController advises that the viewController's topLayoutGuide
property 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.
Upvotes: 10
Reputation: 126309
Go with Martin's suggestion to the question: 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.
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).
BOOL isPortrait = self.interfaceOrientation == UIInterfaceOrientationPortrait;
CGSize statusBarSize = [UIApplication sharedApplication].statusBarFrame.size;
CGFloat statusBarHeight = (isPortrait ? statusBarSize.height : statusBarSize.width);
Upvotes: 104
Reputation: 39181
Here is a Swift way to get screen status bar height:
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
Upvotes: 2
Reputation: 612
I just found a way that allow you not directly access the status bar height, but calculate it.
Navigation Bar height - topLayoutGuide length = status bar height
Swift:
let statusBarHeight = self.topLayoutGuide.length-self.navigationController?.navigationBar.frame.height
self.topLayoutGuide.length
is the top area that's covered by the translucent bar, and self.navigationController?.navigationBar.frame.height
is the translucent bar excluding status bar, which is usually 44pt. So by using this method you can easily calculate the status bar height without worring about status bar height change due to phone calls.
Upvotes: 0
Reputation: 8090
[UIApplication sharedApplication].statusBarFrame.size.height
. But since all sizes are in points, not in pixels, status bar height always equals 20.
Update. Seeing this answer being considered helpful, I should elaborate.
Status bar height is, indeed, equals 20.0f points except following cases:
setStatusBarHidden:withAnimation:
method and its height equals 0.0f points;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 portrait mode 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 UIViewController
and self.interfaceOrientation
is not available, use [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 tiled background 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.
Upvotes: 517
Reputation: 17612
While the status bar is usually 20pt tall, it can be twice that amount in some situations:
Just try it, and you'll see for yourself. Hardcoding the height to 20pt will usually work, until it doesn't.
So I second H2CO3's answer:
statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
Upvotes: 11
Reputation: 1426
By default Status Bar height in iOS is 20 pt
.
More info: http://www.idev101.com/code/User_Interface/sizes.html
Upvotes: 0
Reputation: 75
Using following single line code you can get status bar height in any orientation and also if it is visible or not
#define STATUS_BAR_HIGHT (
[UIApplicationsharedApplication].statusBarHidden ? 0 : (
[UIApplicationsharedApplication].statusBarFrame.size.height > 100 ?
[UIApplicationsharedApplication].statusBarFrame.size.width :
[UIApplicationsharedApplication].statusBarFrame.size.height
)
)
It just a simple but very useful macro just try this you don't need to write any extra code
Upvotes: -6
Reputation: 9351
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.
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.
Upvotes: 5
Reputation:
Try this:
CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
Upvotes: 23