// // UIApplicationSwitchRoot.swift // WOKA // // Created by MacBook Pro on 28/05/24. // import UIKit enum RootViewAnimations{ case login case logout } // MARK: - Extension to UIApplication to manage root view controller transitions with animations. extension UIApplication { // Static variable defining the animation option for login transition. static var loginAnimation: UIView.AnimationOptions = .transitionCrossDissolve // Static variable defining the animation option for logout transition. static var logoutAnimation: UIView.AnimationOptions = .curveLinear // Static method to set the root view controller of the key window with optional animation. public static func setRootView(_ viewController: UIViewController, // isLogin: Bool, animated: Bool = true, duration: TimeInterval = 0.5, completion: (() -> Void)? = nil) { // Safely unwrap the key window of the application. guard let keyWindow = UIApplication.shared.keyWindowInConnectedScenes else { return } // Choose the animation option based on login or logout (here we always use loginAnimation). let options: UIView.AnimationOptions = loginAnimation // If animation is not required, set the root view controller immediately. guard animated else { keyWindow.rootViewController = viewController return } // Perform the transition animation for changing the root view controller. UIView.transition(with: keyWindow, duration: duration, options: options, animations: { // Temporarily disable animations for setting the root view controller. let oldState = UIView.areAnimationsEnabled UIView.setAnimationsEnabled(false) UIApplication.shared.keyWindowInConnectedScenes?.rootViewController = viewController UIView.setAnimationsEnabled(oldState) }) { _ in // Call the completion handler if provided. completion?() } } } // MARK: - The enum AppStoryboard represents different storyboards in the application. enum AppStoryboard: String { // These are the cases of the enum, each representing a storyboard name. case Login = "Login" case Main = "Main" case Home = "Home" case AuthenticationSB = "AuthenticationSB" // Computed property that returns an instance of UIStoryboard for the given case. var instance: UIStoryboard { // Creates and returns a UIStoryboard instance with the name of the enum case and the main bundle. return UIStoryboard(name: self.rawValue, bundle: Bundle.main) } // Generic function to instantiate and return a view controller of the specified type from the storyboard. func viewController(viewControllerClass: T.Type, function: String = #function, line: Int = #line, file: String = #file) -> T { // Get the storyboard ID from the view controller class. let storyboardID = (viewControllerClass as UIViewController.Type).storyboardID // Attempt to instantiate the view controller with the given identifier from the storyboard instance. guard let scene = instance.instantiateViewController(withIdentifier: storyboardID) as? T else { // If the view controller cannot be instantiated, a runtime error is thrown with a detailed message. fatalError("ViewController with identifier \(storyboardID), not found in \(self.rawValue) Storyboard.\nFile : \(file) \nLine Number : \(line) \nFunction : \(function)") } // Return the instantiated view controller. return scene } } // MARK: - Extension to UIViewController to get the storyboard identifier. extension UIViewController { // Computed property to return the class name as the storyboard ID. class var storyboardID: String { return "\(self)" } static func instantiate(from: AppStoryboard) -> Self { return from.viewController(viewControllerClass: self) } }