Home > OS >  How to maintain array content when clicking back navigation bar button to previous View Controller?
How to maintain array content when clicking back navigation bar button to previous View Controller?

Time:03-06

I have two View Controllers A & B.

In ViewController B, I have a button that adds an item to an array with a click

var list = [Items]()
@IBAction func addButton(_ sender: UIButton) {
    let indexPath = IndexPath(row: sender.tag, section: tagPassedOver)
        
        list.append(Items(category: "Toys", name: toys[indexPath.row], price: toysPrice[indexPath.row]))
    
}

ViewController A

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    if self.isMovingFromParent {
        
        // how do i send the data back in here??
    }
}

Problem: When I click the back button in the navigation bar of View Controller B to go to View Controller A, my "list" array has been reset. So, my previous elements are no longer stored in the array, and if I click the button in View Controller B it creates a brand new array. I found something to help here but I do not know what insert in the if statement. Or is there a way to do this with segues? I just need to know how to send data backwards (Lmk if you need more clarification, I had to simplify my code to get an answer for this specific issue)

Goal: be able to go back/forth between views and preserve the contents of my array

CodePudding user response:

One way to accomplish this would be by making your ViewController A be a delegate for ViewController B. If you aren't familiar with delegation, you will just need to define a protocol that declares the tasks the delegate (ViewContollerA) should handle and then add a variable to 'B' to store the delegate. 'A' will need to declare conformance to the delegate protocol and implement it. Then all 'B' needs to do is call it when needed.

In View Controller A:

class ViewControllerA: UIViewController, DataCollectorViewControllerDelegate {
    
    func showViewControllerB() {
        viewControllerB.delegate = self
        viewControllerB.list = dataArray
        //Do stuff to show ViewControllerB
    }
    
    //Will get called when ViewControllerB exits
    func dataViewControllerWillExitWithData(_ dataArray: [MyDataType]){
        //Do something with dataArray
    }
} 

In ViewControllerB:

protocol DataCollectorViewControllerDelegate: AnyObject {
    func dataViewControllerWillExitWithData(_ dataArray: [MyDataType])
}

class ViewControllerB: UIViewController {
    
    weak var delegate: DataCollectorViewControllerDelegate?
    var list = [Items]()
    
    func exit() {
        self.delegate?.dataViewControllerWillExitWithData(list)
        //Do what you need to exit
    }
}

For more about the delegation pattern: delegation

Other things to think about:

Does B need to store data at all? Maybe B can just report to the delegate (A) what selection was made and let A own the data.

  • Related