A. Wood
A. Wood

Reputation: 13

How to prevent UIViewController from re-instantiating during segues?

I have a UITableView inside of a UIViewController (lets call that view controller B) that I fill with objects one at a time. The objects are created in a previous UIViewController (view controller A), and added to the table's data source (which is also view controller B) in the prepare( for segue:_) function of view controller A. This adds that one object to the table, at which point the user can tap an "Add to Table" cell that brings them back to controller A, and the process is repeated. The problem is that each time I return to view controller B, the Table View only has the most recently added object. I believe this is because each segue is creating a new instance of the ViewController it is moving to. How can I prevent this, or find a better place to store the tableview data source that will not be re-instantiated and overwritten as an empty list each time?

View Controller A

class ViewControllerA : UIViewController {

    var object = MyObject(...)

    ...

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let viewB = segue.destination as! ViewControllerB


        viewB.dataSource.append(object) //


    }
}

View Controller B

class ViewControllerB: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var dataSource = [MyObject]()

    //DataSource functions fill table with dataSource array objects
    ...
}

Upvotes: 1

Views: 224

Answers (3)

tc333
tc333

Reputation: 109

You are correct that this is happening because each time you segue back from ViewControllerB to ViewControllerA, ViewControllerB is deallocated from memory, along with its datasource. I would recommend passing a dataSource array from ViewControllerA when you instantiate ViewControllerB in prepareForSegue. Something like this...

class ViewControllerA : UIViewController {
    var selectedItems: MyObject = []
    var object = MyObject(...)

...

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let viewB = segue.destination as! ViewControllerB

    viewB.dataSource = selectedItems
}

That way, ViewControllerA is keeping track of all selected items even after ViewControllerB is deallocated.

Upvotes: 0

Shades
Shades

Reputation: 5616

You can pass the entire array back to ViewController A when you tap that "Add to Table" button. Then, append the new object to the entire list and assign it to the variable in ViewController B

A:

class ViewControllerA : UIViewController {

    var dataSource = [MyObject]()  // Now you have a dataSource variable in both viewControllers
    var object = MyObject()

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        let viewB = segue.destination as! ViewControllerB

        dataSource.append(object)  // Add the new object
        viewB.dataSource = dataSource  // Assign the newly-updated array
    }
}

B:

class ViewControllerB: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var dataSource = [MyObject]()

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        let viewA = segue.destination as! ViewControllerA

        viewA.dataSource = dataSource
    }
}

Upvotes: 0

Fangming
Fangming

Reputation: 25260

The reason you lost your data is because that when view controller B is recreated every time when you trying to do the segue. So to keep the data, you must pass the data back from view controller B to view controller A. Then when you click on something else on view controller A, you need to append the new data to the existing one and then pass to controller B again.

To pass data back, you need to look at unwind segue. Here is a good example of the implementation.

Upvotes: 1

Related Questions