I have two view controllers and two views. In my first view, I set the variable 'currentUser' to false. I need to be able to set 'currentUser' to true in the second view controller.
When trying to reference 'currentUser' from the second view it's not picking it up as 'currentUser' is defined in the first view controller.
How do I carry across variables with segue?
To pass data from the current view controller to the next new view controller (not a previous view controller) using segues, first create a segue with an identifier in the relevant storyboard. Override your current view controller's prepareForSegue method.
You create the unwind segue as per usual - drag to the exit icon in the scene. Now in the object inspector on the left you will see the unwind segue listed below the view controller, first responder and exit icons. You can click on the unwind segue and give it an identifier in the inspector on the right.
Set values from Any ViewController to a Second One using segues
Like this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if(segue.identifier == "yourIdentifierInStoryboard") { let yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass) yourNextViewController.value = yourValue
And in your yourNextViewController class.
class yourNextViewControllerClass { var value:Int! // or whatever
You can call this also programmatically:
self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)
Set values from your DestinationViewController back to your Primary (First) ViewController
1. Implement a protocol, for example create a file called protocol.swift.
protocol changeUserValueDelegate { func changeUser(toValue:Bool) }
2. set the delegate on your second View
class yourNextViewControllerClass { var delegate:changeUserValueDelegate?
3. set the delegate on load (prepareForSegue)
if(segue.identifier == "yourIdentifierInStoryboard") { var yourNextViewController = (segue.destinationViewController as yourNextViewControllerClass) yourNextViewController.delegate = self
4. add Function to FirstViewController
func changeUser(toValue:Bool) { self.currentUserValue = toValue }
5. call this function from your SecondViewController
delegate?.changeUser(true)
6. Set the delegate in your FirstViewController
class FirstViewController: UIViewController, ChangeUserValueDelegate {
The problem here is that your currentUser
variable is of type Bool
, which is a value type. So passing it from your first view controller to your second view controller will in fact create a new Bool
instance. What you need is to pass a reference from your first view controller to your second view controller (see Value and Reference Types for more details on value and reference with Swift).
Thereby, according to your needs/preferences, you may choose one of the three following examples.
Here, we "box" our Bool
inside a class and pass a reference of that class instance to the second view controller.
1.1. Create a CurrentUser
class:
class CurrentUser { var someBooleanValue = true { didSet { print(someBooleanValue) } } }
1.2. Create a UIViewController
subclass for the first view controller:
import UIKit class ViewController1: UIViewController { let currentUser = CurrentUser() override func viewDidLoad() { super.viewDidLoad() currentUser.someBooleanValue = false } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if let viewController2 = segue.destinationViewController as? ViewController2 { viewController2.currentUser = currentUser } } }
1.3. Create a UIViewController
subclass for the second view controller:
import UIKit class ViewController2: UIViewController { var currentUser: CurrentUser? // Link this IBAction to a UIButton or a UIBarButtonItem in the Storyboard @IBAction func toggleBoolean(sender: AnyObject) { if let currentUser = currentUser { currentUser.someBooleanValue = !currentUser.someBooleanValue } } }
Here, we get a weak reference of our first view controller in a closure and pass this closure to the second view controller.
2.1. Create a UIViewController
subclass for the first view controller:
import UIKit class ViewController1: UIViewController { var currentUser = true { didSet { print(currentUser) } } override func viewDidLoad() { super.viewDidLoad() currentUser = false } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if let viewController2 = segue.destinationViewController as? ViewController2 { let closureToPerform = { [weak self] in if let strongSelf = self { strongSelf.currentUser = !strongSelf.currentUser } } viewController2.closureToPerform = closureToPerform } } }
2.2. Create a UIViewController
subclass for the second view controller:
import UIKit class ViewController2: UIViewController { var closureToPerform: (() -> Void)? // Link this IBAction to a UIButton or a UIBarButtonItem in the Storyboard @IBAction func toggleBoolean(sender: AnyObject) { closureToPerform?() } }
Here, we make our first view controller conform to some protocol and pass a weak reference of it to the second view controller.
3.1. Create a custom protocol:
protocol MyDelegate: class { func changeValue() }
3.2. Create a UIViewController
subclass for the first view controller and make it conform to the previous protocol:
import UIKit class ViewController1: UIViewController, MyDelegate { var currentUser = true { didSet { print(currentUser) } } override func viewDidLoad() { super.viewDidLoad() currentUser = false } func changeValue() { currentUser = !currentUser } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if let viewController2 = segue.destinationViewController as? ViewController2 { viewController2.delegate = self } } }
3.3. Create a UIViewController
subclass for the second view controller:
import UIKit class ViewController2: UIViewController { weak var delegate: MyDelegate? // Link this IBAction to a UIButton or a UIBarButtonItem in the Storyboard @IBAction func toggleBoolean(sender: AnyObject) { delegate?.changeValue() } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With