1

In Screen A I collect data from the user and then display it on Screen B using a prepare for segue function. Then I noticed if the user goes to Screen C and then back to Screen B the data is gone. How do I keep the data there.

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var textInput: UITextField!

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let a : BViewController = segue.destination as! BViewController
        a.honey = textInput.text!
    }
}

import UIKit

class BViewController: UIViewController {

    @IBOutlet weak var x: UILabel!

    var honey:String = "default"
    override func viewDidLoad() {
        super.viewDidLoad()
        x.text = honey
    }
}

StoryBoard

Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
Benjamin
  • 17
  • 4
  • How are you going to the third view controller and coming back? Seems like you might be creating a new instance of B. – Rakesha Shastri Sep 17 '18 at 18:28
  • @RakeshaShastri Look at the storyboard picture. I just control dragged the button on Screen B to Screen C and it creates a segue – Benjamin Sep 17 '18 at 18:30
  • Right, you are creating new instance of B. You can set a breakpoint in viewDidLoad of B and make sure. ViewDidLoad is called only once, after initialization, so in your case it will be called again after you press the button in C. Try to use UINavigatoinController - maybe it is what you need – lobstah Sep 17 '18 at 18:42
  • @RakeshaShastri is there any way of not making a new instance of B without using a UINavigationController – Benjamin Sep 17 '18 at 19:29
  • Welcome to StackOverflow. Please read [ask] and [mcve] and then [edit] your question showing the _minimum_ code that demonstrates the problem. i.e remove empty methods and template comments. – Ashley Mills Sep 17 '18 at 20:17
  • @AshleyMills I didn't want to add minimal code because I've seen people ask for more code and to show more a lot – Benjamin Sep 17 '18 at 20:22
  • People ask to see more code when something is missing that is part of the problem. `didReceiveMemoryWarning()` that only calls its super implementation is _not_ relevant to the problem. Comments that were added as part of the template are _not_ relevant code. `viewDidLoad()` that only calls its super implementation is _not_ relevant code. Please [edit] your question and remove all irrelevant code. – Ashley Mills Sep 17 '18 at 20:25
  • Creating a [mcve] is a good first step at solving the problem yourself - remove the trees so you can see the wood! – Ashley Mills Sep 17 '18 at 20:30

2 Answers2

0

Then I noticed if the user goes to Screen C and then back to Screen B the data is gone. How do I keep the data there.

I see two problems:

  1. It looks like you're not actually going back to the "screen B" that you left. The storyboard shows a push segue from B to C, and another from C to B. So I think what's happening is that you're creating another Screen B, separate from the first one. You should look into unwinding the push segue instead of adding another one. Remember: the screens you create in a storyboard aren't individual objects -- they're more like patterns or prototypes of objects, and they can be instantiated multiple times.

  2. More generally, it's a good idea to avoid storing your program's data in views or even in view controllers. The M in MVC stands for model, which is meant to be a separate object (or group of objects) that manage the data and business logic for your app. Using a model wouldn't solve problem #1, but it'll still help you avoid a lot of "hey, where did my data go?" issues.

Caleb
  • 124,013
  • 19
  • 183
  • 272
  • So lets say someone in Screen B enters their name and then there is a algorithm that calculates their favorite football team based on their name. Are you saying that algorithm should not be inside the viewcontroller code? – Benjamin Sep 17 '18 at 22:51
  • Yes. Extend your example into something nontrivial and pretty quickly you'll want to have multiple view controllers that all have access to the app's data. If you keep business logic and data in a view controller, it's only available in that one controller. – Caleb Sep 18 '18 at 04:14
  • So would you put it in a swift file instead of a cocoa pods file? And how would that file access the information the user types – Benjamin Sep 18 '18 at 20:32
  • Cocoapods is a dependency manager, so I don't think that's what you really mean. Check out [*Model-View-Controller*](https://developer.apple.com/library/archive/documentation/General/Conceptual/CocoaEncyclopedia/Model-View-Controller/Model-View-Controller.html) in Apple's documentation. – Caleb Sep 18 '18 at 21:18
0

This is a common problem.
You need to pass the data into each new VC when you instantiate it. The data you want to save can be an instance variable in each VC.

Or you need to save the data you want to persist into NSUserDefaults or use Core Data. If you go this route, once you save the data into one of these places, you can access it anytime from anywhere.

user798719
  • 9,619
  • 25
  • 84
  • 123