I have an OnboardingViewController
which available to access from app's settings in a modal style.
When a user opens the app first time I want to show him the OnboardingVC
in the same modal style (with an upper tabs effect, like so: Screenshot) as it loads if to present it from the Settings.
SceneDelegate
setup:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let scene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: scene)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "OnboardingViewController") as! OnboardingViewController
window?.rootViewController = controller
window?.makeKeyAndVisible()
}
The problem it's always appear in a full screen, without the above modal tabs effect at the top.
How to solve it?
You can't present a UIViewController
(modally or fullscreen) which is window's rootViewController
.
To show Onboarding screen when user open app for the first time, set Home Screen/Login Screen (or any screen you want) as rootViewController
in SceneDelegate
. Then from that UIViewController
you can check if user open app for first time or not. Depending on that you can show the Onboarding screen.
You must embed the rootViewController
in a UINavigationViewController
to present/push another UIViewController
In SceneDelegate.swift modify the code like below.
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let scene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: scene)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
//embed in UINavigationController
let navController = UINavigationController(rootViewController: controller)
window?.rootViewController = navController
window?.makeKeyAndVisible()
}
Then in the Home screen (i assume it as HomeViewController) check the status of first opening and present Onboarding screen.
class HomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "OnboardingViewController") as! OnboardingViewController
controller.modalPresentationStyle = .formSheet
self.present(controller, animated: true)
}
}
You can get the rootViewController
from anywhere in the app by using the code below. And then present any ViewController you want to show.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "OnboardingViewController") as! OnboardingViewController
controller.modalPresentationStyle = .formSheet
let rootVC = UIApplication.shared.windows.first!.rootViewController
rootVC?.present(controller, animated: true)