Swift
iOS Development
Device Orientation
Mobile Programming
Swift Tutorial

Getting device orientation in Swift

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In iOS, "orientation" can mean two different things: the physical orientation of the device and the orientation of your interface. Most confusion comes from reading one when you actually need the other.

Device Orientation Versus Interface Orientation

UIDevice.current.orientation tells you how the hardware is positioned. UIWindowScene.interfaceOrientation tells you how the app interface is currently laid out.

These can differ. For example:

  • the device can be face up while the interface stays portrait
  • orientation lock can keep the UI fixed
  • on iPad, window size and multitasking can matter more than raw device rotation

So the first step is deciding which signal you really need.

Reading Physical Device Orientation

If you need the hardware orientation, use UIDevice.current.orientation.

swift
1import UIKit
2
3let orientation = UIDevice.current.orientation
4
5switch orientation {
6case .portrait:
7    print("portrait")
8case .portraitUpsideDown:
9    print("upside down")
10case .landscapeLeft:
11    print("landscape left")
12case .landscapeRight:
13    print("landscape right")
14case .faceUp:
15    print("face up")
16case .faceDown:
17    print("face down")
18case .unknown:
19    print("unknown")
20@unknown default:
21    print("unhandled")
22}

This is the right choice for camera behavior, motion-sensitive UI, or logic that truly depends on physical position.

Listening For Orientation Changes

If the value can change while the screen is visible, observe orientation change notifications.

swift
1import UIKit
2
3final class ViewController: UIViewController {
4    override func viewDidLoad() {
5        super.viewDidLoad()
6
7        UIDevice.current.beginGeneratingDeviceOrientationNotifications()
8        NotificationCenter.default.addObserver(
9            self,
10            selector: #selector(orientationChanged),
11            name: UIDevice.orientationDidChangeNotification,
12            object: nil
13        )
14    }
15
16    @objc private func orientationChanged() {
17        let orientation = UIDevice.current.orientation
18        print("new orientation:", orientation.rawValue)
19    }
20
21    deinit {
22        NotificationCenter.default.removeObserver(self)
23        UIDevice.current.endGeneratingDeviceOrientationNotifications()
24    }
25}

This pattern is reliable when you need updates instead of a one-time check.

Reading Interface Orientation

If what you really care about is how the app is being displayed, use the scene's interface orientation.

swift
1import UIKit
2
3if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
4    let interfaceOrientation = scene.interfaceOrientation
5    print(interfaceOrientation.isLandscape)
6}

This is often better than device orientation for layout decisions, because it reflects the UI rather than the raw hardware state.

Layout Is Often Better Than Orientation Checks

A lot of code that asks for orientation really wants responsive layout. In those cases, use size classes, view bounds, or Auto Layout constraints instead of branching on orientation.

For example, if the goal is "show two columns when the screen is wide," checking width is usually better than checking orientation.

swift
1override func viewDidLayoutSubviews() {
2    super.viewDidLayoutSubviews()
3
4    if view.bounds.width > view.bounds.height {
5        print("wide layout")
6    } else {
7        print("tall layout")
8    }
9}

This adapts better to iPad multitasking and resizable scenes.

A SwiftUI Pattern

In SwiftUI, you can still observe orientation notifications if needed:

swift
1import SwiftUI
2
3struct ContentView: View {
4    @State private var orientation = UIDevice.current.orientation
5
6    var body: some View {
7        Text(orientation.isLandscape ? "Landscape" : "Portrait or other")
8            .onReceive(NotificationCenter.default.publisher(
9                for: UIDevice.orientationDidChangeNotification
10            )) { _ in
11                orientation = UIDevice.current.orientation
12            }
13            .onAppear {
14                UIDevice.current.beginGeneratingDeviceOrientationNotifications()
15            }
16    }
17}

Even there, many layout problems are better solved with geometry and adaptive views instead of raw orientation values.

Common Pitfalls

The most common mistake is using UIDevice.current.orientation for layout decisions when interface orientation or view size would be more accurate.

Another mistake is ignoring .unknown, .faceUp, and .faceDown. Those are valid device states and they can appear at app startup or while the device is flat.

Developers also forget to begin orientation notifications before expecting change events.

Finally, orientation checks can become brittle on iPad. If the real requirement is adaptive layout, rely on view size or size classes instead of assuming portrait versus landscape is the full story.

Summary

  • Use UIDevice.current.orientation for physical device position.
  • Use UIWindowScene.interfaceOrientation for the app's interface orientation.
  • Observe UIDevice.orientationDidChangeNotification when you need live updates.
  • Prefer layout-driven logic over orientation checks when the problem is really screen size.
  • Handle .unknown, .faceUp, and .faceDown explicitly.

Course illustration
Course illustration

All Rights Reserved.