1

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?

devJo
  • 63
  • 7
  • As Moshe said, the issue is that your first view controller is keeping a strong reference to that second view controller. That’s not necessary. Just make that reference to the second view controller a local variable within the `accessoryButtonTappedForRowWith` method. Also, you haven’t shared `CustomUINavigationBar`, but make sure it’s keeping weak reference to its delegate. – Rob Mar 25 '20 at 20:50
  • Once you get your immediate question behind you, you might want to revisit your class names. As a matter of convention, class names always start with an uppercase letter. We start with lowercase letter for variables, properties, etc., but types always start with uppercase letter. And, if you want to simplify the renaming process (simultaneously changing them everywhere, including storyboards) you can right click on the class name and choose “Refactor” » “Rename...”. – Rob Mar 25 '20 at 20:54
  • Thanks Rob, I will refactor my code later on taking into considering your much appreciated advice :) – devJo Mar 25 '20 at 22:04

1 Answers1

1

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.

Moshe Gottlieb
  • 3,963
  • 25
  • 41
  • Thank you very much Moshe, your response sorted out my problem. Much appreciated again, and I totally agree on the casting point. – devJo Mar 25 '20 at 20:53