iOS 13
status bar height
iOS development
Swift programming
iPhone UI design

How to get the status bar height in iOS 13?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

In iOS 13 and later, getting the status bar height is not as straightforward as it was in earlier versions. Apple deprecated the UIApplication.shared.statusBarFrame property in iOS 13, and the status bar height varies across devices. On older iPhones with a home button, it is 20 points. On iPhones with a notch (iPhone X and later), it is 44 points. During phone calls or hotspot usage, it can expand further. This article covers the correct ways to retrieve the status bar height in iOS 13+, with working Swift code and explanations of why each approach works.

Why the Status Bar Height Matters

The status bar sits at the very top of the screen, displaying the time, battery level, and network status. If your layout does not account for its height, content can end up hidden behind it. This is especially important for apps that use custom navigation bars or position views manually rather than relying entirely on Auto Layout with safe area guides.

The status bar height also changes dynamically. During a phone call, the status bar grows taller on pre-notch devices (from 20 to 40 points). On notch devices, the status bar height stays the same during calls, but the system adds a green indicator to the Dynamic Island or the top-left corner. Your layout needs to handle these changes gracefully.

Starting with iOS 13, Apple introduced the UIWindowScene API as part of the multi-window support on iPad. This is now the recommended way to get the status bar height:

swift
1func getStatusBarHeight() -> CGFloat {
2    guard let windowScene = UIApplication.shared.connectedScenes
3        .first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
4    else {
5        return 0
6    }
7    
8    return windowScene.statusBarManager?.statusBarFrame.height ?? 0
9}

This code finds the active UIWindowScene, accesses its statusBarManager, and reads the statusBarFrame height. This works correctly on all devices running iOS 13 and later.

You can call this from a view controller:

swift
1override func viewDidLoad() {
2    super.viewDidLoad()
3    
4    let statusBarHeight = getStatusBarHeight()
5    print("Status bar height: \(statusBarHeight)")
6}

Accessing from a UIView

If you need the status bar height from within a UIView rather than a view controller, you can access the window scene through the view's own window:

swift
1extension UIView {
2    var statusBarHeight: CGFloat {
3        guard let windowScene = window?.windowScene else { return 0 }
4        return windowScene.statusBarManager?.statusBarFrame.height ?? 0
5    }
6}

Use this in layoutSubviews or after the view has been added to the window hierarchy. Before the view is attached to a window, window will be nil and this will return 0.

Method 2: Using Safe Area Insets

For most layout purposes, you do not actually need the raw status bar height. What you need is the safe area, which accounts for the status bar, navigation bar, home indicator, and any other system UI. The safe area insets give you this information automatically:

swift
1override func viewDidLayoutSubviews() {
2    super.viewDidLayoutSubviews()
3    
4    let topInset = view.safeAreaInsets.top
5    print("Top safe area inset: \(topInset)")
6}

On a device with a notch, safeAreaInsets.top returns 44 or 47 points (depending on the exact model) when there is no navigation bar, and a larger value when a navigation bar is present. On a home-button iPhone, it returns 20 points for just the status bar.

If you are using Auto Layout, you can simply constrain views to the safe area layout guide and let the system handle the offset:

swift
1myContentView.translatesAutoresizingMaskIntoConstraints = false
2
3NSLayoutConstraint.activate([
4    myContentView.topAnchor.constraint(
5        equalTo: view.safeAreaLayoutGuide.topAnchor
6    ),
7    myContentView.leadingAnchor.constraint(
8        equalTo: view.leadingAnchor
9    ),
10    myContentView.trailingAnchor.constraint(
11        equalTo: view.trailingAnchor
12    ),
13    myContentView.bottomAnchor.constraint(
14        equalTo: view.safeAreaLayoutGuide.bottomAnchor
15    )
16])

This is the preferred approach for most apps. You rarely need the exact status bar height when you use safe area constraints.

Method 3: The Deprecated Approach (Pre-iOS 13)

Before iOS 13, developers commonly used this property:

swift
// DEPRECATED in iOS 13
let height = UIApplication.shared.statusBarFrame.height

This still compiles but generates a deprecation warning. It also does not work correctly in multi-window scenarios on iPad. If you are maintaining an older codebase, you should migrate to the window scene approach.

Handling Dynamic Height Changes

The status bar height can change at runtime, for example when a phone call starts or ends on pre-notch devices. To respond to these changes, observe the willChangeStatusBarFrame notification:

swift
1override func viewDidLoad() {
2    super.viewDidLoad()
3    
4    NotificationCenter.default.addObserver(
5        self,
6        selector: #selector(statusBarFrameChanged),
7        name: UIApplication.willChangeStatusBarFrameNotification,
8        object: nil
9    )
10}
11
12@objc func statusBarFrameChanged(_ notification: Notification) {
13    if let frame = notification.userInfo?[
14        UIApplication.statusBarFrameUserInfoKey
15    ] as? CGRect {
16        print("New status bar height: \(frame.height)")
17        // Update your layout here
18    }
19}

On modern devices with a notch or Dynamic Island, status bar height changes are less common, but it is still good practice to handle them if you are positioning views relative to the status bar.

SwiftUI Approach

In SwiftUI, you almost never need to query the status bar height directly. The safeAreaInset environment handles it automatically:

swift
1struct ContentView: View {
2    var body: some View {
3        GeometryReader { geometry in
4            VStack {
5                Text("Top inset: \(geometry.safeAreaInsets.top)")
6                Spacer()
7            }
8        }
9    }
10}

The safeAreaInsets.top value from GeometryReader includes the status bar height. SwiftUI views respect safe areas by default, so content is automatically positioned below the status bar without any manual calculation.

Common Pitfalls

Querying the status bar height too early. If you check the height in viewDidLoad, the view's window might not be set yet, which means the window scene lookup returns nil. Use viewDidAppear or viewDidLayoutSubviews for reliable results.

Hardcoding the height. Never assume the status bar is 20 or 44 points. The height varies by device, orientation, and system state. Always query it dynamically.

Ignoring the deprecated warning. Using UIApplication.shared.statusBarFrame still works in many cases, but it returns incorrect values in iPad multi-window mode and will eventually be removed. Migrate to the window scene API.

Confusing status bar height with safe area insets. On notch devices, safeAreaInsets.top equals the status bar height when there is no navigation bar. But when a navigation bar is present, safeAreaInsets.top includes both the status bar and the navigation bar. If you specifically need just the status bar height, use the statusBarManager approach.

Summary

In iOS 13 and later, use UIWindowScene.statusBarManager.statusBarFrame.height to get the exact status bar height. For layout purposes, prefer safe area insets and the safe area layout guide, which handle the status bar, navigation bar, and home indicator automatically. Avoid the deprecated UIApplication.shared.statusBarFrame property. Always query the height dynamically rather than hardcoding values, since it varies across devices and changes during phone calls on older hardware.


Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.