How do you pass data between view controllers in Swift?
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...
}
}
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
}
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, :)
Just need to follow 3 steps, let's assume you want to pass data from ViewControllerA to ViewControllerB:
- create a segue between ViewControllerA and ViewControllerB
- name the segue with a Identifier in the attributes inspector of it
- 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 oflet destinationVC:ViewControllerClass = segue.destinationViewController
This is tested on Swift 2.1.1 and it works for me.