2

I have 2 view controller with navigation controller. First view controller has 4 text field and second view controller has 4 text field. To navigate first view controller to second I am using following code:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
var destinationVC:UIViewController
destinationVC = storyboard.instantiateViewController(withIdentifier: "SecondVC") as! SecondVC
navigationController?.show(destinationVC, sender: self)

To first from second view controller I am using

navigationController?.popViewController(animated: true)

However, even if the fields I have filled in first view controller keep the values when I go from first to second values I have written have disappear because of popviewcontroller method. What is the best way to remember values in second view controller?

atalayasa
  • 3,310
  • 25
  • 42

4 Answers4

2

You can have singleton where you can store the values as dictionary(or something else)

class Settings: NSObject {
   static let shared = Settings()

   public var dictionaryToStore: [String: String]?

   private init() {
      super.init()
   }
}

And in your controller when poping

Settings.shared.dictionaryToStore = {"key1": textfield1.text, "key2": textfield2.text, ...  
}

And in viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()
    textfield1.text = Settings.shared.dictionaryToStore["key1"]
    textfield2.text = Settings.shared.dictionaryToStore["key2"]
    ...
}

Also you can create custom object and store it.

EDIT 1 ** To have variables after app has been terminated you can save dictionary in UserDefaults

class Settings: NSObject {
   static let shared = Settings()

   public var dictionaryToStore: [String: String]? {
    set(newValue) {
        let defaults = UserDefaults.standard
        defaults.set(newValue, forKey: "SomeKey")
    }
    get {
        let defaults = UserDefaults.standard
        let loadedValue = defaults.object(forKey: "SomeKey")
        return loadedKey
    }
}

   private init() {
      super.init()
   }
}
Arthur Sahakyan
  • 566
  • 3
  • 17
  • The question is not about storing and loading values rather than about wrong logic of things author did and wrong cracked expectations. – SwiftStudier Jan 18 '18 at 07:53
  • Thanks for helpful comment, I need to ask one more thing which is if we kill the application do that variables keep in storage? – atalayasa Jan 18 '18 at 08:45
  • @SwiftStudier could you please tell me where is wrong logic of mine so I can develop it ? – atalayasa Jan 18 '18 at 08:50
  • 1
    Sure. The only mistake is using different instances of SecondVC while expecting for all changes in it to be saved for the second or third time access. It's like perform some changes on one instance of something, then create and show a new one and expect for changes from first instance to appear on another instance of something - it does not work this way. – SwiftStudier Jan 18 '18 at 09:18
  • Also, `dictionaryToStore`-example won't work after application termination since all the data is stored in app memory - it should be stored (and later loaded) in database (coredata, realm, etc) or, if there are few values, UserDefaults can be used. – SwiftStudier Jan 18 '18 at 09:18
  • @SwiftStudier he can save dictionary in user defaults and that will work after app terminate, I don't see in his question such point that solution must work after app terminated. And this is the right way to do such things. – Arthur Sahakyan Jan 18 '18 at 11:30
  • With no doubt that will work, but you answer different question. Also, userdefaults is not designed to store entire app content, so please have a depeer look on it – SwiftStudier Jan 18 '18 at 11:33
  • @SwiftStudier I edited my answer, I don't know what you mean saying "but you answer different question", his question how can he get variables after app got terminated and/or ViewController removed from stack ? I answered how can he do that... And can you please explain me, how will you keep data after app was terminated, if not in UserDefaults(or similar place)? And yes keeping viewController after he MUST be removed from stuck is bad practice – Arthur Sahakyan Jan 18 '18 at 11:44
  • @ArthurSahakyan also true. The question about remembering values was caused by mistake in overall logic of implementing things, so in that case there is no need to store values manually (nothing about termination in original post and for now too) rather than fix the mistkae I described and everythig would be fine. You can read a lot about storing data in ios with the help of google if u need – SwiftStudier Jan 18 '18 at 11:47
  • @SwiftStudier if he will write as you advise, code will be not flexible, what will happen if in future he wants to navigate in that viewController from other ViewController ? He must use code that I posted ... , it is better to write more flexible code at the start, but however I think it is better to finish our discussion, Your solution is also right, but he asked for better way to solve the problem. – Arthur Sahakyan Jan 18 '18 at 13:02
  • .. and you misunderstood the reason of the problem. Yup, lets end up – SwiftStudier Jan 18 '18 at 13:21
1

The key reason for values not to be remembered on the SecondVC is that you're using new instances of SecondVC each time you open it.

So you better create an instance (first 3 lines of your code do that job) of SecondVC once, somewhere in the beginning of FirstVC, and use it in show() func everytime you need to show SecondVC instead of creating multiple instance of SecondVC each time.

In that case you'll see all values "remembered" in the SecondVC.

SwiftStudier
  • 2,272
  • 5
  • 21
  • 43
  • So if I create first 3 line in my viewDidLoad function, aren't they disappear when I use popViewController? – atalayasa Jan 18 '18 at 08:58
  • Nope, the will disappear. Your `var destinationVC` stuff must be placed somewhere in global scope of your FirstVC, not in specific function of it like viewDidLoad. Since you create an instance of SecondVC in FirstVC once, keep it for a long time and use it anytime you want to show SecondVC (instead of initializing a new one), everything would be fine and all changed commited to textField in SecondVC won't get lost. Here is a quick-made demo for you https://www.sendspace.com/file/lma5kr – SwiftStudier Jan 18 '18 at 09:15
  • Thanks for demo it is helpful now I understood it. – atalayasa Jan 19 '18 at 08:57
0

You can use key-value storage like NSUserDefaults in your secondViewController to save data when viewController will disappear and load on viewDidLoad. Or save your data in some struct/object instance and pass it when you push secondViewController.

0

if you want to pass data from you first view controller to second view

how to pass data from first viewcontroller to second viewcontroller

in above code though you are making new instance of you view controller still you can pass data by setting variable of second view controller in first view controller before

navigationController?.show(destinationVC, sender: self)

like

destnationVC.variableTOSet = valueTopass

and then

navigationController?.show(destinationVC, sender: self)

and then in second view controller use that variable to use value

so that how you can pass data from your first controller to second view controller

now if you want to pass data from your second viewController to first controller then you can use delegates

Devil Decoder
  • 966
  • 1
  • 10
  • 26