I am working on a simple iOS Swift app. The app has 2 view controllers and a button that has been programmed to segue to the other view controller like so:
@IBAction func pushMe(sender: AnyObject) {
self.performSegueWithIdentifier("changeIt", sender: nil)
}
The above works but I want to be able to save 2 variables from the current view controller and make them available to the view controller I am segueing to. So I did this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "changeIt" {
var testVar1 = "Hello"
var testVar2 = "World"
}
}
In the view controller that I am segueing to I added:
var testVar1:String!
var testVar2:String!
The app works but as soon as I try to access testVar1 or testVar2, the app crashes. I am not sure why this isn't working as intended?
Because variables were not initialized, you omitted destination view controller. Use the code below
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "changeIt" {
let dvc = segue.destinationViewController as! YourDestinationViewController
dvc.testVar1 = "Hello"
dvc.testVar2 = "World"
}
}
if segue.identifier == "changeIt" {
var testVar1 = "Hello"
var testVar2 = "World"
}
All you are doing here is making new, completely separate local variables called testVar1
and testVar2
. They are not, by some miraculous wishful thinking, the same as the instance properties testVar1
and testVar2
belonging to the view controller you are segueing to. How can they be? That code never even mentions that view controller at all! If you want to set a property of a view controller, you need to talk to that view controller.
Think of it this way. Suppose the Dog class has a name
property and you want to set a Dog instance's name
. Do you do it by saying this?
let d = Dog()
let name = "Fido"
No! That creates a name
, but it isn't the dog's name. You need to say this:
let d = Dog()
d.name = "Fido"
So in your code, you need to use the segue to get a reference to the destination view controller and set its properties.
You can solve it creating the variables on destination ViewController
class OtherViewController : UIViewController {
var testVar1 : String = ""
var testVar2 : String = ""
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var message = "\(self.testVar1) \(self.testVar2)"
print(message)
}
}
The UIStoryboardSegue has a destinationViewController property. It's an instance to the end point view controller you want to reach. Then now you can do this:
class SourceViewController : UIViewController {
//...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//Some code before
var destination = segue.destinationViewController as! OtherViewController
destination.testVar1 = "Hello"
destination.testVar2 = "World"
//Some code after
}
}