Programmatically Setting a Root View Controller in iOS Using Scene Delegation

Programmatically Setting a Root View Controller in iOS

In this article, we will explore the process of programmatically setting a root view controller in an iOS application. This involves understanding how to modify the SceneDelegate class and its associated methods to achieve our desired outcome.

Introduction

When developing an iOS application, it’s common to use storyboards to design the user interface. However, when working with EPUB readers like the one provided by the EpubPDFReader library, we may encounter difficulties in customizing the library according to our requirements. In this article, we’ll focus on programmatically setting a root view controller instead of displaying a table view with options.

Understanding Scene Delegation

In iOS 13 and later versions, Apple introduced a new concept called Scene Delegation. This system allows us to manage multiple scenes within an application, which can be useful in various scenarios.

To set a root view controller programmatically, we need to work with the SceneDelegate class, which is responsible for managing scene connections and transitions.

The Problem with AppDelegate

The original code snippet provided uses the AppDelegate class to set the root view controller. However, in iOS 13 and later versions, the window property is not available in AppDelegate. Instead, we need to work with the SceneDelegate.

// Before (iOS 13 and later)
self.window.rootViewController = self.navigationController;

// After (iOS 13 and later)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let rootVC = storyboard?.instantiateViewController(identifier: "LoginViewController") as? LoginViewController else {
    print("ViewController not found")
    return
}

Setting the Root View Controller Programmatically

To set a root view controller programmatically, we need to create an instance of SceneDelegate and override its associated methods.

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Create a new window scene
        guard let windowScene = (scene as? UIWindowScene) else { return }

        window = UIWindow(windowScene: windowScene)

        // Load the storyboard
        let storyboard = UIStoryboard(name: "Main", bundle: nil)

        // Get the root view controller
        guard let rootVC = storyboard?.instantiateViewController(identifier: "LoginViewController") as? LoginViewController else {
            print("ViewController not found")
            return
        }

        // Create a new navigation controller with the root view controller
        let nav = UINavigationController(rootViewController: rootVC)

        // Set the root view controller of the window
        window?.rootViewController = nav

        // Make the key and visible
        window?.makeKeyAndVisible()
    }
}

Explanation and Context

In this code snippet, we create an instance of SceneDelegate and override its associated method scene(_:willConnectTo:options:). Within this method, we create a new window scene and load the storyboard.

We then get the root view controller from the storyboard using its identifier. If the view controller is not found, we print an error message and return from the function.

Next, we create a new navigation controller with the root view controller as its root view controller. Finally, we set the root view controller of the window to the navigation controller and make the key and visible.

Conclusion

In this article, we explored the process of programmatically setting a root view controller in an iOS application using Scene Delegation. We discussed how to modify the SceneDelegate class and its associated methods to achieve our desired outcome.

By following this guide, you should be able to set a root view controller programmatically in your iOS applications.

Further Reading

Example Use Cases

  • EPUB Readers: When working with EPUB readers like the EpubPDFReader library, you may need to programmatically set a root view controller instead of displaying a table view with options.
  • Customization: If you want to customize your app’s user interface without using storyboards, you can use Scene Delegation to set the root view controller programmatically.

Conclusion

By understanding how to modify the SceneDelegate class and its associated methods, you can programmatically set a root view controller in your iOS applications. This guide provides a comprehensive overview of the process, including explanations, examples, and further reading resources.


Last modified on 2024-02-08