-1

I have two view controllers. One is navigated to with a "show" segue. There is a back button in the UINavigationBar that I have not changed. The back button goes back to the initial view controller. In the view controller with the back button, I am storing data in a variable.

How can I pass this data to my initial view controller?

I have tried:

viewWillDisappear(_ animated: Bool) {
    let vc = ViewController()
    vc.data = items
}

but the data in the initial view controller is empty when printed.

I've attempted to use:

prepare(for segue: ...)

but I'm not sure what segue the back button uses.

I can't seem to add an action of the back button to my view controller either.

user28434'mstep
  • 6,290
  • 2
  • 20
  • 35
Nathaniel
  • 70
  • 1
  • 10
  • `Let vc = ViewController()` That's creating a whole new object, not the one you think of. – Larme Mar 05 '19 at 13:21
  • Possible duplicate of [Pass data back to previous viewcontroller](https://stackoverflow.com/questions/19343519/pass-data-back-to-previous-viewcontroller) – Rocky Mar 05 '19 at 13:22

2 Answers2

1

vc isn't the same controller as controller which you're going back to.


Create closure variable in second controller with array of your models as parameter

class SecondViewController: UIViewController {
    var callback: (([Item]) -> Void)?
}

then in first controller's prepare(for:sender:) assign destination's callback and declare that you want to change first controller's data when callback is called

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "yourSegueIdentifier" {
        let destinationVC = segue.destination as! SecondViewController
        destinationVC.callback = { items in
            self.data = items
        }
    }
}

Then when you need to (means in second controller's viewWillDisappear) call callback with given items

override func viewWillDisappear(_ animated: Bool) {
    callback?(items)
}
Robert Dresler
  • 10,580
  • 2
  • 22
  • 40
0

You could use a delegate. First, create a protocol:

protocol getItemsDelegate {
    func getItems(_ items: [String])
}

In your first view controller's class definition add getItemsDelegate:

class myFirstViewController: UIViewController,getItemsDelegate

Add this to the prepare method in your first view controller:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let vc = segue.destination as! mySecondViewController
    vc.delegate = self
}

Lastly, in your first view controller, add this:

func getItems(_ items: [String]) {
    // Do something with items
}

In your second view controller, declare the following property:

var delegate: getItemsDelegate?

Then:

override func viewWillDisappear(_ animated: Bool) {
   delegate?.getItems(items)
}

This is just another way to do it.

Floyd Resler
  • 1,786
  • 3
  • 22
  • 41
  • Using viewWillDisappear for passing data back is very common mistake. The problem is viewWillDisappear will be called every time user starts swipe back, and if user stops on half way you will stay on same viewController but delegation method will be activated and it can cause bugs. – Vahagn Gevorgyan Mar 05 '19 at 19:23
  • Never thought of that possibility of a user stopping a swipe. However, in this case, I believe there is a Back button which wouldn't require a swipe. But that potential bug is good to keep in mind! – Floyd Resler Mar 07 '19 at 16:39
  • In navigation controller swipe back is enabled by default, and as a part of good UX it is not recommended to disable it. So yes, it is very important to keep that potential bug in mind. – Vahagn Gevorgyan Mar 08 '19 at 20:49