简体   繁体   中英

Save data in Model between Views in iOS Swift

I'm very new in iOS development and I'm stuck on how to save data into the model when accessing several views..

I have a pizza selector (for the sake of this example I'm going to simplify the model), my root file have 2 buttons label as: "Size","Dough", each time you press a button you navigate to a new ViewController within a show segue, in here you have a picker to select from 3 types of sizes or doughs.

What I'm not capable of doing is to save the data from one of the views when returning from the other, I mean, if you press the size button and select for example "large" when you clic on accept it returns to the ViewController class and I have the value of "large" but now if you press on the "Dough" button and select "thin" when you come back it only have the "thin" value the previous size values is lost...

This is the ViewController (root file):

class ViewController: UIViewController {

    let pizza = Pizza(tamano: "", masa: "")

    enum Constantes {
        case Tamano
        case Masa
    }

    @IBOutlet weak var tamanoLabel: UIButton!
    // Almacenamos el tamaño de la pizza
    var tamanoPvara:String?
    var tipoMasa:String?

    // Almacenamos cuales tipos/ingredientes aun no tengo
    var compruebaEleccion = [Constantes.Tamano:false]


    override func viewDidLoad() {
        super.viewDidLoad()
        print("tamano: \(pizza.tamano) masa: \(pizza.masa)")
        // Do any additional setup after loading the view, typically from a nib.
        //        if let (pizza.model["Tamano"] != "") {
        //            labelTamanoPizza.text = pizza.model["Tamano"]
        //        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func btnConfirmacion(sender: AnyObject) {
        // Variable para saber si estan todos los pasos hechos
        print("tamano: \(pizza.tamano) masa: \(pizza.masa)")

    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if (segue.identifier == "tamanoPizza") {
            print("tamaño")
            let destinationViewController = segue.destinationViewController as! ViewTamanoController
            destinationViewController.pizza = self.pizza
        }
        if (segue.identifier == "TipoMasa") {
            print("masa")
            let destinationViewController = segue.destinationViewController as! ViewTipoMasaController
            destinationViewController.pizza = self.pizza
        }
    }


}

This is the ViewSizeController:

class ViewTamanoController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {


    @IBOutlet weak var tamanoSelector: UIPickerView!
    @IBOutlet weak var labelTamano: UILabel!

    let pickerData = ["Chica","Mediana","Grande"]

    var pizza = Pizza?()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        tamanoSelector.dataSource = self
        tamanoSelector.delegate = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return 1
    }
    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return pickerData.count
    }

    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return pickerData[row]
    }

    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        labelTamano.text = pickerData[row]
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if (segue.identifier == "fromTamanoToController") {
            print("segue tamaño")
            let viewController = segue.destinationViewController as! ViewController
//            viewController.tamanoPizza = labelTamano.text;
            viewController.pizza.tamano = labelTamano.text
        }
    }

    @IBAction func btnAceptar(sender: AnyObject) {
//        print("aceptar tamaño")

        pizza!.tamano = labelTamano.text
         print(pizza!.tamano)
    }
}

And this is the ViewDoughController

class ViewTipoMasaController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate  {

    @IBOutlet weak var tipoMasaLabel: UILabel!
    @IBOutlet weak var tipoMasaSelector: UIPickerView!

    let pickerData = ["Delgada","Crujiente","Gruesa"]

    var pizza = Pizza?()


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        tipoMasaSelector.dataSource = self
        tipoMasaSelector.delegate = self

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return 1
    }
    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return pickerData.count
    }

    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return pickerData[row]
    }

    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        tipoMasaLabel.text = pickerData[row]
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if (segue.identifier == "fromTipoMasaToController") {
            let viewController = segue.destinationViewController as! ViewController
//            viewController.tipoMasa = tipoMasaLabel.text;
            viewController.pizza.masa = tipoMasaLabel.text
        }
    }

    @IBAction func btnAceptar(sender: AnyObject) {

        pizza?.masa = tipoMasaLabel.text
        print(pizza!.masa)
    }

}

I know this is kind of easy question but any help will be appreciated

Thank you so much

I think I found your problem. In the details ViewControllers you are performing a new segue, which means you are creating each time a new parent ViewController. What you have to do is to dismiss the detail View Controller. You don't need the methods prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) in the Details ViewControllers.

Your btnAceptar function would be like that:

@IBAction func btnAceptar(sender: AnyObject) {

        pizza?.masa = tipoMasaLabel.text
        print(pizza!.masa)
        self.dismissViewControllerAnimated(true, completion: nil)
    }

With dismissViewController you are actually returning to the first parent View Controller, and not the new one.

Now, you have to pass the parent ViewController the values for the dough and the size, and you can not do it so easy as you tried. You have to ways of doing that: Notifications or Delegates. You have here an easy example: Pass data when dismiss modal viewController in swift

Instead of the method "backFromCamera" you will have to make a prococol with the methods "setDough" and "setSize" for example.

Have fun ;)

the reason is because the root view controller is reloading new instance of let pizza = Pizza(tamano: "", masa: "") every time it loads.

take the line let pizza = Pizza(tamano: "", masa: "") out of root view controller or get it from class instance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM