Øyvind Hauge beat me to the same solution method, but as I had already started with a more detailed answer, I'll add it as well.
Let's say your two view controllers are named as follows:
- Master/entry point:
ViewController
(vcA)
- Secondary view:
ViewControllerB
(vcB)
You set up the segue from (vcA) -> (vcB)
as you have done in you example
/* in ViewController.swift */
// ...
// segue ViewController -> ViewControllerB
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!)
{
if segue.identifier == "viewNext" {
let viewControllerB = segue.destinationViewController as! ViewControllerB
viewControllerB.dataPassed = labelOne.text
}
}
The somewhat tricky step next is that, using this method, the segue used for passing data back from (vcB)
to (vcA)
is also added to the source of (vcA)
, as an @IBAction
method (rather than, as could possibly be expected, added to the source of (vcB)
).
/* in ViewController.swift */
// ...
// segue ViewControllerB -> ViewController
@IBAction func unwindToThisView(sender: UIStoryboardSegue) {
if let sourceViewController = sender.sourceViewController as? ViewControllerB {
dataRecieved = sourceViewController.dataPassed
}
}
You thereafter connect say, a button in (vcB)
to this unwind action in (vcA)
via the manual Exit
segue in (vcB)
:
Below follows a complete example of passing text from (vcA)
to (vcB)
; (possibly) modifying that text via an UITextField
, finally returning the (possibly) modified text to (vcA)
.
(vcA)
source:
/* ViewController.swift: Initial view controller */
import UIKit
class ViewController: UIViewController {
var dataRecieved: String? {
willSet {
labelOne.text = newValue
}
}
@IBOutlet weak var labelOne: UILabel!
@IBAction func buttonOne(sender: UIButton) {
performSegueWithIdentifier("viewNext", sender: self)
}
// set default labelOne text
override func viewDidLoad() {
super.viewDidLoad()
labelOne.text = "Default passed data"
}
// segue ViewController -> ViewControllerB
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!)
{
if segue.identifier == "viewNext" {
let viewControllerB = segue.destinationViewController as! ViewControllerB
viewControllerB.dataPassed = labelOne.text
}
}
// segue ViewControllerB -> ViewController
@IBAction func unwindToThisView(sender: UIStoryboardSegue) {
if let sourceViewController = sender.sourceViewController as? ViewControllerB {
dataRecieved = sourceViewController.dataPassed
}
}
}
(vcB)
source (note that the UITextFieldDelegate
delegate here is only used for "locally" mutating the value of the dataPassed
property, which will be returned to (vcA)
and assigned to dataRecieved
property of the latter)
/* ViewControllerB.swift */
import UIKit
class ViewControllerB: UIViewController, UITextFieldDelegate {
var dataPassed : String?
@IBOutlet weak var textField: UITextField!
// set default textField text to the data passed from previous view.
override func viewDidLoad() {
super.viewDidLoad()
textField.text = dataPassed
// Handle the user input in the text field through delegate callbacks
textField.delegate = self
}
// UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
// User finished typing (hit return): hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(textField: UITextField) {
dataPassed = textField.text
}
}
Example execution:
prepareForSegue
in your unwinding view controller and access thedestinationViewController
which will be the view controller you are unwinding to. You will probably want to give the unwind segue and identifier in your storyboard – Glaudiaexit
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. – Glaudia