skip to Main Content

Iv been searching and reading many SO articles and just can’t seem to get this to work.

I have a view controller called Startup which does a few web requests etc then takes the user to the login screen.

upon logging on I’m using this code to try and open the content view controller called Home after dismissing the login view controller.

self.dismiss(animated: true, completion: {
        let mainStoryboard: UIStoryboard = UIStoryboard(name:"Main",bundle:Bundle.main)
        let secondViewController: Home = mainStoryboard.instantiateViewController(withIdentifier: "home") as! Home
        self.presentingViewController?.present(secondViewController, animated: true, completion: nil)
    })

my problem is that the Login VC dismisses fine but doesn’t open the Home VC because self.presentingViewController is nil.

Any help would be appreciated,

2

Answers


  1. You need to get topViewController when you dismissed the viewController.
    For getting topViewController you can use extension below.

    extension UIApplication {
    class func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
        if let navigationController = controller as? UINavigationController {
            return topViewController(controller: navigationController.visibleViewController)
        }
        if let tabController = controller as? UITabBarController {
            if let selected = tabController.selectedViewController {
                return topViewController(controller: selected)
            }
        }
        if let presented = controller?.presentedViewController {
            return topViewController(controller: presented)
        }
        return controller
    }}
    

    Then you can present new viewController over topViewController

    self.dismiss(animated: true, completion: {
        let mainStoryboard: UIStoryboard = UIStoryboard(name:"Main",bundle:Bundle.main)
        let secondViewController: Home = mainStoryboard.instantiateViewController(withIdentifier: "home") as! Home
        let topVC = UIApplication.topViewController()
    
        topVC?.present(secondViewController, animated: true, completion: nil)
    })
    
    Login or Signup to reply.
  2. The answer already given is fine; I just want to expand on the nature of the problem here.

    The issue is that we have a login screen that we want to use just once. When it has been passed through, we want to proceed to a base screen, and from now on, when the app launches, we will always start at the base screen.

    The problem of launching from the login screen or the base screen, I leave to one side. Let’s just talk about how the login screen and the base screen should relate, when the login screen is used. I can think of three approaches:

    • Present the base screen from the login screen without dismissing the login screen. I know it sounds nutty, but why not? Just present the base screen and give the user no way to go back to the login screen. The base screen now covers the whole interface and we can proceed to normal use of the app.’

    • Rip out the whole interface and replace it. A lot of people do this: you just change the window’s root view controller to the base screen. I dislike this, however.

    • Start with a parent view controller that the user never actually interacts with. The login screen is the child of that parent. Replace the login screen with the base screen, using any desired transition. That is the solution I actually prefer.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search