0

I know that normally, when a UIViewController A presents another UIViewController B, the presentedViewController property of A is set to B. So A in retained in memory.

Simply, I want to A to present B, but then have A get cleaned up as it will never be returned to.

For a more complete explanation and rationale, in my app I have a UINavigationController that may have a bunch of screens in the hierarchy. At some point (e.g. the use logs out), I want to present a new view controller (login) by calling self.present(loginViewController, animated: true, completion: nil). However, there is no chance the app will ever come back to the UINavigationController by calling "dismiss" from the login controller. If a login is performed, the login view controller will "present" a new UINavigationController.

I want the original UINavigationController and all of its hierarchy to get cleaned up as there might be many screens in the hierarchy seemingly that will never get used again.

(Also, in this case, when the user started the app, they were "auto logged in", so the UINavigationController is the root controller. And as such, when logging out, it can't "dismiss" itself to back to the login screen.)

Thanks!

SuperDuperTango
  • 1,398
  • 1
  • 14
  • 32

3 Answers3

1

You cannot make the presenting view controller vanish from behind the presented view controller. But...

First point: View controllers are fairly lightweight, so there's really nothing wrong with never coming back to the presenting view controller.

Second point: If the problem is that you want the app to launch differently (i.e. with a different root view controller) depending on the user's logged-in state, then the place to take care of that is in your implementation of application:didFinishLaunchingWithOptions:.

Third point: If this is really a problem, then perhaps you need to rethink your whole architecture. Maybe you don't want a presented view controller at all, but rather a view controller that is substituted for the first view controller. There are many ways to arrange that.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • to the first point: It's more that I have a UINavigationController that may have a couple to a couple dozen screens in it's hierarchy. I want to get rid of all of them (but to your point, maybe that still doesn't matter). – SuperDuperTango Nov 14 '16 at 18:41
  • To your second point: no, launching differently isn't what I'm looking for. – SuperDuperTango Nov 14 '16 at 18:42
  • I think your third point is what i'm looking for. I'm not sure how to substitute a view controller. Time for more googling/SOing... :) – SuperDuperTango Nov 14 '16 at 18:43
  • Maybe the problem here is that you have your whole app backwards. Maybe the "logged out" view controller should be the main view controller, and the navigation controller should be the presented view controller. That way, when we are logged in, there is only one unseen view controller, which is lightweight, and when we are logged out, the whole navigation controller complex is gone. – matt Nov 14 '16 at 18:49
0

This question is similar to the question enter link description here

For your convenience, I add my answer below.

You can achieve this with code similar to

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: <Identifier as in Storyboard of B>)
(UIApplication.shared.delegate as! AppDelegate).window?.rootViewController = vc

If you would like to include a transition, you could replace the last line with something as the following:

UIView.transition(from: currentRootViewController!.view, to: vc.view, duration: 0.8, options: .transitionCrossDissolve, completion: { (_) in
      (UIApplication.shared.delegate as! AppDelegate).window?.rootViewController = vc
})
Community
  • 1
  • 1
Carien van Zyl
  • 2,853
  • 22
  • 30
0

As I understand you have a root UINavigationController where you present different View Controllers whether the app has a user logged in or not.If that is the case :

if (user != nil){
myNavigationController.setViewControllers([*/Initialize your first ViewController*/])
}else {
myNavigationController.setViewControllers([*/Initialize your LoginViewController/])
}

If the user logsOut/logsIn just send a local notification that tells navigation controller that the user state has changed and check if a user exists.

Also make sure that all your View Controllers are being de-initialized so they don't stay in memory.

unniverzal
  • 803
  • 10
  • 17