Tomasero
Tomasero

Reputation: 577

How do you pass data between view controllers in Swift?

I tried creating global variables and updating the information when the view is loaded but data isn't being rendered.

GLOBAL VARIABLES

var viewName:String = ""
var viewDuration:String = ""
var viewPeriod:String = ""
var viewMinAmp:String = ""
var viewMaxAmp:String = ""
var viewStep:String = ""
var viewType:String = ""

Is there a more efficient way of passing information other than having global variables?

@IBOutlet var txtName: UITextField!
@IBOutlet var txtDuration: UITextField!
@IBOutlet var txtPeriod: UITextField!
@IBOutlet var txtMinAmp: UITextField!
@IBOutlet var txtMaxAmp: UITextField!
@IBOutlet var txtStep: UITextField!
@IBOutlet var txtType: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    setInfo(viewName, duration: viewDuration, period: viewPeriod, minAmp: viewMinAmp, maxAmp: viewMaxAmp, step: viewStep, type: viewType)
}

func setInfo(name: String, duration: String, period: String, minAmp: String, maxAmp: String, step: String, type: String) {
    txtName.text = name
    txtDuration.text = duration
    txtPeriod.text = period
    txtMinAmp.text = minAmp
    txtMaxAmp.text = maxAmp
    txtStep.text = step
    txtType.text = type
}

Upvotes: 16

Views: 42912

Answers (5)

Jeffrey Kozik
Jeffrey Kozik

Reputation: 549

If you don't actually want to pass data between view controllers but rather simply want to store a global variable you can do this:

This gives a great explanation for how to do this in Swift 5: https://www.hackingwithswift.com/example-code/system/how-to-save-user-settings-using-userdefaults

Summary:

To set a value:

let defaults = UserDefaults.standard
defaults.set("value", forKey: "key")

To get a String value:

let key = defaults.object(forKey: "StringKey") as? [String] ?? [String]()

To get integer value:

let key = defaults.integer(forKey: "IntegerKey")

Upvotes: 0

Saqib Omer
Saqib Omer

Reputation: 5477

For Swift 3.0

final class Shared {
     static let shared = Shared() //lazy init, and it only runs once

     var stringValue : String!
     var boolValue   : Bool!
}

To set stringValue

Shared.shared.stringValue = "Hi there"

to get stringValue

 if let value = Shared.shared.stringValue {
        print(value)
 }

For Swift version below 3.0

You can pass data between views using singleton class. It is easy and efficient way. Here is my class ShareData.swift

import Foundation

class ShareData {
    class var sharedInstance: ShareData {
        struct Static {
            static var instance: ShareData?
            static var token: dispatch_once_t = 0
        }

        dispatch_once(&Static.token) {
            Static.instance = ShareData()
        }

        return Static.instance!
    }


    var someString : String! //Some String

    var selectedTheme : AnyObject! //Some Object

    var someBoolValue : Bool!
}

Now in my ViewControllerOne I can set above variable.

//Declare Class Variable

let shareData = ShareData.sharedInstance

override func viewDidLoad() {
    self.shareData.someString ="Some String Value"
}

And in my ViewControllerTwo I can access someString as

let shareData = ShareData.sharedInstance
override func viewDidLoad() {
    NSLog(self.sharedData.someString) // It will print Some String Value
}

Upvotes: 24

Byron Luo
Byron Luo

Reputation: 11

Just need to follow 3 steps, let's assume you want to pass data from ViewControllerA to ViewControllerB:

  1. create a segue between ViewControllerA and ViewControllerB
  2. name the segue with a Identifier in the attributes inspector of it
  3. override the prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) at ViewControllerA

For step#3,:

  • if you are not using swift 2.1, please follow @Scott Mielcarski 's answer at this question
  • for people who are using swift 2.1, or who get error "Cannot convert value of type 'UIViewController' to specified type 'your view Controller class name', After following @Scott Mielcarski 's answer at this question, Please use:let destinationVC:ViewControllerClass = segue.destinationViewController as! ViewControllerClass instead of let destinationVC:ViewControllerClass = segue.destinationViewController

    This is tested on Swift 2.1.1 and it works for me.

Upvotes: 1

Scott Mielcarski
Scott Mielcarski

Reputation: 760

One solution would be to override prepareForSegue(segue:sender:) from within the view controller which contains the data that you wish to pass to the destination view controller.

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if (segue.identifier == "YourSegueName") {
        //get a reference to the destination view controller
        let destinationVC:ViewControllerClass = segue.destinationViewController as! ViewControllerClass

        //set properties on the destination view controller
        destinationVC.name = viewName
        //etc...
    }
}

Upvotes: 34

Ke Yang
Ke Yang

Reputation: 921

Personally, I prefer ways as follow:

  • If you want to jump forward between two view controllers (from A to B), as -pushViewController:animated: in navigation, you can define a property of model for Controller B and expose it publicly, then set this property explicitly before jumping from Controller A, it's pretty straightforward;

  • In case you want to jump backward from Controller B to A, use Delegate+Protocol mode. Controller B drafts a public protocol and own a "delegate" property, any object who would like to be the delegate of Controller B shall comply and implement its protocol(optionally). then prior to the jumping-backward, Controller B makes its delegate perform certain action(s) listed in protocol, the data could be transferred in this way;

  • Under certain circumstance, you may want to transfer data from a Controller(or controllers) to other multiple Controllers, use Notification mechanism if this is the case.

Apple has detailed instructions about delegate mode, notification mode in official documentation, check them out in XCode, :)

Upvotes: 5

Related Questions