If you are quite new in Swift, sooner or later you will face such view hierarchy:
Dashboard -> Login -> Register
So when app starts, you are using Dashboard view controller as root, and if user is not authorized, you need to show Login view. In case you are pushing Login view from navigation controller, case is simple, but if you need to use “present”, it is not, because calling “dismiss” on view controller is causing to dismiss only this specific view. In our case calling “dismiss” on Register view, will remove it but instead of dashboard, user will still see Login page. To solve this, you need to dismiss all view controllers from Dashboard which is first one using:
self.view.window?.rootViewController?.dismiss(animated: false, completion: nil)
And how Dashboard will know is user is logged in? In simplest form, you can use NotificationCenter, so in Dashboard you may add:
NotificationCenter.default.addObserver(self, selector: #selector(onDidRegistered(_:)), name: .didRegistered, object: nil)
and later in you controller code:
@objc func onDidRegistered(_ notification: Notification) { self.view.window?.rootViewController?.dismiss(animated: false, completion: nil) }
Also for notification itself, you need to register its name:
extension Notification.Name { static let didRegistered = Notification.Name("didRegistered") }
And finally in Register view after user has registered successfully and is authorized, all you have to do is call:
NotificationCenter.default.post(name: .didRegister, object: nil)
Of course there are more elegant ways to communicate between controllers, but this one is simplest.