I am make two ViewControllers, how can I change rootViewController from ViewController() to MainView()? Here my code in SceneDelegate
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.makeKeyAndVisible()
window?.backgroundColor = UIColor.black
if isNewUser == true {
window?.rootViewController = ViewController()
} else {
window?.rootViewController = MainView()
}
This work fine when I test both isNewUser = true and isNewUser = false when I ran the app.
In my ViewController
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//Show the welcome screen, blah.
//Accept the location, blah.
//After accepted everything, change isNewUser to false in UserDefault.Standard
print("App is restart")
}
}
class MainView: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
print("Welcome to AiOO!")
}
}
Both work fine, but for example, when I finish accepted the agreement or accepted location, something like that for first time run the app...it will set to isNewUser to false in UserDefault.standard. So only one thing I am stuck, how can I restart app or switch the rootViewController to MainView()??
UPDATED: RestartApp, no luck when I click "Complete" button, there no UITabBarControl and will not call MainView until I kill app and open again, it work :( Here my full codes below:
In SceneDelegate:
var versioncheck = "1.0.0.0"
class SceneDelegate: UIResponder, UIWindowSceneDelegate, RestartApp {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
sceneRestore()
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.makeKeyAndVisible()
window?.backgroundColor = UIColor(named: "Main Background")
restartApp()
}
func restartApp() {
if !UserDefaults.standard.bool(forKey: "New User") {UserDefaults.standard.set(true, forKey: "New User")}
let isNewUser = UserDefaults.standard.bool(forKey: "New User")
print(isNewUser) // It will keep say "true" even change to false in UserDefault
if isNewUser == true {
window?.rootViewController = ViewController()
} else if versioncheck != "1.0.0.0" {
window?.rootViewController = NewUpdate()
} else {
window?.rootViewController = MainView()
}
}
}
ViewController
protocol RestartApp {
func restartApp()
}
class ViewController: UIViewController {
var delegate: RestartApp?
override func viewDidLoad() {
super.viewDidLoad()
welcomePage()
}
}
When I click "Complete" button, it will call:
@objc func welcomeChangeGoToMain () {
UserDefaults.standard.set(false, forKey: "New User")
print(UserDefaults.standard.bool(forKey: "New User")) //It said "false"
welcomeTitle.removeFromSuperview()
welcomeSubline.removeFromSuperview()
welcomeNext.removeFromSuperview()
welcomeRequest.removeFromSuperview()
self.delegate?.restartApp()
}
You can create a delegate protocol gets called whenever the isNewUser value gets changed and call it's delegate function inside the scene class in order to present the view controller based on the value. Like Below:
inside you SceneDelegate class :
// don't forget to assign the RestartApp Delegate here
class SceneDelegate: UIResponder, UIWindowSceneDelegate, RestartApp {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.makeKeyAndVisible()
restartApp()
}
and create the restartApp function inside sceneDelegate as well
func restartApp() {
let isNewUser = UserDefaults.standard.bool(forKey: "Key")
if isNewUser == true {
window?.rootViewController = ViewController()
} else {
window?.rootViewController = ViewController2()
}
}
at the end where you want the restart function gets called create the protocol and it's delegate call like below:
protocol RestartApp {
func restartApp()
}
class ViewController2: UIViewController {
var delegate: RestartApp?
override func viewDidLoad() {
super.viewDidLoad()
UserDefaults.standard.set(true, forKey: "Key")
view.backgroundColor = .yellow
print("VC2")
self.delegate?.restartApp() // this should be called wherever you want to restart the app ( inside an action or a function depends on your need )
}
}
To sum up , what happens here that the app start it calls willConnectTo function inside SceneDelegate class and this one calls the restart app and call the VC based on the last value save in IsNewUser , then inside you VC every time you call the self.delegate.restartApp() , it calls the restart func inside the SceneDelegate and call the VC based on your isNewUser Value .