iOS development
view controller
iOS programming
UIKit
Swift

How to find topmost view controller on iOS

Interview Questions practice on Codemia

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

Browse interview questions

Finding the topmost view controller in an iOS application is an essential task for developers interested in presenting alerts, modals, or performing navigation tasks without direct reference to view controllers in the hierarchy. This common scenario often occurs when code-based UI updates or interactions need to reliably target the current active screen.

Understanding View Controller Hierarchies

In iOS, applications are primarily organized using a hierarchy of view controllers. This hierarchy is established when view controllers are embedded within each other using navigation controllers, tab bar controllers, or presented modally. The topmost view controller is essentially the one that is currently visible to the user, covering the entire screen or within the context of a container.

The Importance of the Topmost View Controller

Identifying the topmost view controller is crucial for:

  • Ensuring UI updates, such as alerts or modals, are presented from the correct view.
  • Avoiding redundancies and potential crashes due to attempting to display views on offscreen or unloaded view controllers.
  • Maintaining a seamless and intuitive user experience without unnecessary interruptions.

Steps to Find the Topmost View Controller

1. Understanding the Root View Controller

Every iOS application has a root view controller, which is at the base of the view hierarchy. It usually is set in the AppDelegate or SceneDelegate for applications using storyboards or set programmatically.

2. Traversing the View Controller Hierarchy

To find the current visible view controller, you'll start from the root and traverse the hierarchy:

Sample Swift Code

Below is a function that retrieves the topmost view controller in a typical iOS application:

swift
1func getTopViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
2    if let nav = base as? UINavigationController {
3        return getTopViewController(base: nav.visibleViewController)
4    }
5    
6    if let tab = base as? UITabBarController, let selected = tab.selectedViewController {
7        return getTopViewController(base: selected)
8    }
9    
10    if let presented = base?.presentedViewController {
11        return getTopViewController(base: presented)
12    }
13    
14    return base
15}

3. Dealing with Special Container View Controllers

In apps with complex navigation flows, special view controllers like UISplitViewController or custom container view controllers might need additional handling to correctly determine the topmost view controller.

4. Consideration for Scene-based Apps

For projects using scene delegates (iOS 13 and above), the approach slightly changes since the keyWindow property is deprecated.

swift
1func getTopViewController(base: UIViewController? = UIApplication.shared.connectedScenes
2    .filter { $0.activationState == .foregroundActive }
3    .compactMap { $0 as? UIWindowScene }
4    .first?.windows
5    .filter { $0.isKeyWindow }.first?.rootViewController) -> UIViewController? {
6    // Navigation follows the same pattern as before
7}

5. Ensuring Thread-Safety

Since UI updates must happen on the main thread, ensure that this detection runs within the main thread context if the function involves UI manipulation:

swift
1DispatchQueue.main.async {
2    if let topViewController = getTopViewController() {
3        // Proceed with presenting alerts or other UI
4    }
5}

Summary Table

Key AspectDescription
Root View ControllerStarting point in hierarchy; defined in AppDelegate/SceneDelegate.
Navigation ControllersUse .visibleViewController to find active controller inside navigation.
Tab Bar ControllersUse .selectedViewController for active tab context.
Presented View ControllersRecursively check .presentedViewController.
Scene-based AppsAdapt for scene delegates to access key window root view controller.
Thread SafetyEnsure operations on top view controller occur on the main thread.

Additional Considerations

  • Modal Presentations: Modally presented view controllers are always the topmost within their context.
  • Transitions: During transitions, care must be taken to identify whether a controller is about to be presented or just dismissed, as this could affect the visible hierarchy.
  • Debugging Hierarchies: Use Xcode's View Debugger to visually inspect and validate view controller hierarchies during development.

By applying the principles and methods outlined above, developers can effectively manage UI interactions in complex iOS app architectures, ensuring that user interactions occur smoothly and as intended within the current context.


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.