Swift - How to detect orientation changes
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Detecting when a user rotates their device is essential for building responsive iOS apps. Whether you need to rearrange a layout, resize a video player, or switch between grid and list views, your app must respond to orientation changes smoothly. This article covers every major technique in UIKit and SwiftUI, explains the critical difference between device and interface orientation, and helps you choose the right approach for your situation.
UIDevice.orientationDidChangeNotification
The most straightforward way to detect orientation changes in UIKit is to observe the UIDevice.orientationDidChangeNotification notification. This fires whenever the physical device rotates, regardless of whether the interface actually changes.
Remember to call beginGeneratingDeviceOrientationNotifications() or the notification will never fire. Also note that faceUp and faceDown are device-only orientations that do not correspond to any interface orientation.
UIDeviceOrientation vs UIInterfaceOrientation
Understanding the difference between these two types is critical because confusing them is one of the most common mistakes in iOS orientation handling.
UIDeviceOrientation describes how the physical device is held. It includes six cases: portrait, portraitUpsideDown, landscapeLeft, landscapeRight, faceUp, and faceDown. It comes from the accelerometer.
UIInterfaceOrientation describes how the app's UI is displayed. It only includes four cases: portrait, portraitUpsideDown, landscapeLeft, and landscapeRight. It comes from the window scene.
A key subtlety is that landscapeLeft means opposite things for each type. UIDeviceOrientation.landscapeLeft means the device is rotated so the home button is on the right, while UIInterfaceOrientation.landscapeLeft means the interface is rotated to the left. Use interface orientation when you need to know how your UI is laid out.
viewWillTransition(to:with:)
For UIKit view controllers, overriding viewWillTransition(to:with:) is the recommended way to react to size changes caused by rotation. This method gives you the new size before the transition animation begins.
This method is preferred over notification-based approaches when you need to coordinate your own animations with the system rotation animation.
traitCollectionDidChange for Size Classes
Size classes provide a more abstract way to handle layout changes. Instead of checking for specific orientations, you respond to changes between compact and regular size classes.
Size classes are the right choice when you want your layout logic to work across iPhones, iPads, and multitasking split views without hard-coding device-specific orientation checks.
SwiftUI Orientation Detection
In SwiftUI, you can read the horizontal size class from the environment. This is the SwiftUI equivalent of trait collection changes.
For cases where you need the actual device orientation in SwiftUI, you can combine a notification observer with a state variable.
Common Pitfalls
- Forgetting
beginGeneratingDeviceOrientationNotifications()meansUIDevice.orientationDidChangeNotificationnever fires, and your handler is silently ignored. - Using
UIDeviceOrientationto determine interface layout includesfaceUpandfaceDownwhich have no corresponding interface orientation, leading to unexpected behavior. - Not using the transition coordinator in
viewWillTransitioncauses your custom layout changes to appear out of sync with the system rotation animation. - Hard-coding orientation checks instead of size classes breaks on iPads in split view, where the device may be in landscape but your app has a compact width.
- Checking orientation in
viewDidLoadmay return.unknownbecause the device orientation may not be determined yet at that point in the lifecycle.
Summary
- Use
UIDevice.orientationDidChangeNotificationwithNotificationCenterfor direct device rotation detection in UIKit. - Override
viewWillTransition(to:with:)to animate layout changes alongside the system rotation transition. - Understand that
UIDeviceOrientationtracks the physical device, whileUIInterfaceOrientationtracks the app's UI. These are not interchangeable. - Use
traitCollectionDidChangeand size classes for adaptive layouts that work across all device types and multitasking modes. - In SwiftUI, use
@Environment(\.horizontalSizeClass)for declarative layout switching based on available space. - Always prefer size classes over explicit orientation checks for forward-compatible, multitasking-ready code.
Related reading
- Swift - How to detect orientation changes
- Swift - How to dismiss all of view controllers to go back to root
- Swift - How to dismiss all of view controllers to go back to root
- Swift - how to make custom header for UITableView?
- Swift - How to remove a decimal from a float if the decimal is equal to 0?
- Swift - How to remove a decimal from a float if the decimal is equal to 0?
- Swift - How to replace characters in a String?
- Swift - Integer conversion to Hours/Minutes/Seconds
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack 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.