Search code examples
iosswiftuiviewcontrollerpresentviewcontroller

Removing all previously loaded ViewControllers from memory iOS Swift


I am currently editing a code previously written, In the application, The first viewController is a table view controller named: ListViewController that has several elements, each selection of row creates a new instance of a view controller and presents it modally. but in those view controllers, instead of dismissing them, the previous developer again created the instance of the ListViewController and presents it modally to go back.

The application is obviously using alot of memory.

Dismissing the view controllers is not an option.

if I pop view controllers in the stack one by one, this doesn't work, each view has popups etc presented on viewdidAppear.

I need to remove all previously loaded ViewControllers from memory and present a viewController such that there are no instances of any ViewControllers left in the memory. Is it possible? Is there a way i can goto say a new ViewController called HomeViewController ensuring that all previously loaded instances of all view controllers are released.

The scenario is as following:

                         ListViewController 
                     /            |            \ 
             AViewController  BViewController  CViewController

ListViewController has 3 elements

A B C

user can tap any of them, that results in presenting a ViewController. and from each of the view controllers, when back button is pressed, The ListViewController is presented.

Views are presented using the following code:

if let listViewController = storyboard!.instantiateViewControllerWithIdentifier("ListViewController") as? ListViewController {
                    self.presentViewController(listViewController, animated: true, completion: nil)
                }

Solution

  • I am not sure it will work. Try this. Before presenting any new ViewController.

    Make a method in AppDelegate

    func switchControllers(viewControllerToBeDismissed:UIViewController,controllerToBePresented:UIViewController) {
            if (viewControllerToBeDismissed.isViewLoaded && (viewControllerToBeDismissed.view.window != nil)) {
                // viewControllerToBeDismissed is visible
                //First dismiss and then load your new presented controller
                viewControllerToBeDismissed.dismiss(animated: false, completion: {
                    self.window?.rootViewController?.present(controllerToBePresented, animated: true, completion: nil)
                })
            } else {
            }
        }
    

    Now lets say you move like this

    ViewController --> You click a button and present a SecondViewController

    So currently we have ViewController and SecondViewController in memory.

    Now when you click some button in SecondViewController in order to present a ThirdViewController, then SecondViewController must dismiss. So in SecondViewController button Press

    @IBAction func buttonPress(_ sender: AnyObject) {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
    
        let controllerToBePresented = self.storyboard?.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
        appDelegate.switchControllers(viewControllerToBeDismissed: self, controllerToBePresented: controllerToBePresented)
    }
    

    So now we have ViewController and ThirdViewController in memory.
    SecondViewController is removed from memory.

    Better solution is to keep your controllers in UINavigationController stack because you can get an array of all ViewControllers pushed on stack.