De-initialzing a ViewController after dismissal?

412 views Asked by At

I have two viewControllers in my App, the code for the first viewController is as illustrated below:

           import UIKit

            class firstViewController: UIViewController {

              // The below two variables will be passed from the firstViewController to the secondViewController then back again from the secondViewController to the firstViewController:

              var selectedRowValue: Int = 0

              var selectedSectionValue: Int = 0

              let main = UIStoryboard(name: "Main", bundle: nil)

               lazy var secondViewController = main.instantiateViewController(withIdentifier: "secondViewController")

             override func viewDidLoad() {

             super.viewDidLoad()

              }

    // The below function will be triggered when the user tap on a specific tableView cell detailClosure icon. This is when the needed data get sent from this viewController to the secondViewController:

            func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {

             let secondViewControllerProperties = secondViewController as! secondViewController

              secondViewControllerProperties.receivedSelectedSectionValueFromFirstVc = indexPath.section

              secondViewControllerProperties.receivedSelectedRowValueFromFirstVc = indexPath.row

    // The below is the relevant content of a UILabel inside the tapped tableView cell by the user that get send to the secondViewController for it to be displayed as its NavigationBar title:

             secondViewControllerProperties.selectedUniversalBeamSectionDesignation = arrayWithAllDataRelatedToUbsSections.filter({ $0.sectionSerialNumber == "\(arrayWithAllSectionsSerialNumbers[indexPath.section])" }).map({ $0.fullSectionDesignation })[indexPath.row]

self.present(secondViewControllerProperties, animated: true, completion: nil)

             }

            }

    // The below extension inside the firstViewController is used to pass data back from the secondViewController to the firstViewController:

        extension firstViewController: ProtocolToPassDataBackwardsFromSecondVcToFirstVc {

            func dataToBePassedUsingProtocol(passedSelectedTableSectionNumberFromPreviousVc: Int, passedSelectedTableRowNumberFromPreviousVc: Int) {

                self.selectedRowValue = passedSelectedTableRowNumberFromPreviousVc

                self. selectedSectionValue = passedSelectedTableSectionNumberFromPreviousVc

        }

        }

Below is the code inside the second view controller:

import UIKit

class secondViewController: UIViewController {

    weak var delegate: ProtocolToPassDataBackwardsFromSecondVcToFirstVc?

// The below variables get their values when the data get passed from the firstViewController to the secondViewController:

    var receivedSelectedRowValueFromFirstVc: Int = 0

    var receivedSelectedSectionValueFromFirstVc: Int = 0

   var selectedUniversalBeamSectionDesignation: String = ""

// Inside the below navigationBar declaration, its labelTitleText will depend on the tapped tableViewCell by the user inside the firstViewController:

lazy var navigationBar = CustomUINavigationBar(navBarLeftButtonTarget: self, navBarLeftButtonSelector: #selector(navigationBarLeftButtonPressed(sender:)), labelTitleText: "UB \(selectedUniversalBeamSectionDesignation)", navBarDelegate: self)

    override func viewDidLoad() {

        super.viewDidLoad()

        view.addSubview(navigationBar)

}

// The below gets triggered when the user hit the back button inside the navigationBar of the secondViewController. This is where using the Protocol data get passed back to the firstViewController: 

extension secondViewController: UINavigationBarDelegate {

    @objc func navigationBarLeftButtonPressed(sender : UIButton) {

        if delegate != nil {

            delegate?.dataToBePassedUsingProtocol(passedSelectedTableSectionNumberFromPreviousVc: self.selectedTableSectionNumberFromPreviousViewController, passedSelectedTableRowNumberFromPreviousVc: self.selectedTableRowNumberFromPreviousViewController)

        }

        dismiss(animated: true) {}

    }

}

However, what I am noticing is whenever the secondViewController gets dismissed when the user hit on the back button inside the navigationBar of the secondViewController. The secondViewController does not get de-initialized, and therefore, whenever I press on a different cell inside the tableView inside the firstViewController, the navigationBar title that gets displayed inside the secondViewController is still the same as the one displayed when I pressed the first time. Since the secondViewController did not get de-initialzied and thus, I am seeing the same values as the first time it got initialized.

My question is how to de-initialize the secondViewController when it gets dismissed, so that every time I tap on a different cell inside the tableView inside the firstViewController a new secondViewController gets initialized?

1

There are 1 answers

1
Moshe Gottlieb On BEST ANSWER

Your code generates secondViewController once and reuses it (it's a property).

               lazy var secondViewController = main.instantiateViewController(withIdentifier: "secondViewController")

It means it will live until the first view controller is destroyed, and of course - will be reused.
Instead, you should create it as needed.

func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
             // Create the second view controller
             let secondViewController = main.instantiateViewController(withIdentifier: "secondViewController")

             let secondViewControllerProperties = secondViewController as! secondViewController

              secondViewControllerProperties.receivedSelectedSectionValueFromFirstVc = indexPath.section

              secondViewControllerProperties.receivedSelectedRowValueFromFirstVc = indexPath.row

    // The below is the relevant content of a UILabel inside the tapped tableView cell by the user that get send to the secondViewController for it to be displayed as its NavigationBar title:

             secondViewControllerProperties.selectedUniversalBeamSectionDesignation = arrayWithAllDataRelatedToUbsSections.filter({ $0.sectionSerialNumber == "\(arrayWithAllSectionsSerialNumbers[indexPath.section])" }).map({ $0.fullSectionDesignation })[indexPath.row]

self.present(secondViewControllerProperties, animated: true, completion: nil)

             }

            }

Remove the lazy var of course, it is no longer needed.
Also, you could just do:
let secondViewController = main.instantiateViewController(withIdentifier: "secondViewController") as! SecondViewController instead of casting it later, it's a bit cleaner.