Swift How to passing data over view controller using Segue? - swift

I want to do like this
passing Data from A to C
like: keying some string in A, and click Button to B, then click Button to C.
show string in C's Label
I find some passing Data like this
ex:
in aClass
let bController = segue.destinationVieController
bController.string = "xxx"
But it just A to B
What should I do to passing Data from A to C ?
Now, I use NSNotificationCetner to complete this work,but I want to learn how to use segue closure
If it's really easy, please tell me keyword
because I just search A to B...
thanks!

You are passing string from A->B using segue, so you have the string now in Controller B. Pass the same string from B-> C using segue like below
let cController = segue.destinationVieController
cController.string = string
where string is the variable in Controller B which you have assigned value while segueing from A->B

You can immediately perform the segue from b->c in prepare for segue
//VCA
override func prepareForSegue(segue : UISegue, sender: AnyObject?) {
if segue.identifier == "AtoB" {
//Cast destination VC as a your B VC
let bVC = segue.destinationViewController as! BVC
//Set b's .string property to the string property you're going to send to c
bVC.string = self.string
//perform the segue that goes from b to c
bVC.performSegueWithIdentifier("BtoC")
}
}
//VCB
override func prepareForSegue(segue : UISegue, sender: AnyObject?) {
if segue.identifier == "BtoC" {
//Cast destination VC as a your C VC
let cVC = segue.destinationViewController as! CVC
//Set c's .string property to the string property that you now go from
cVC.string = self.string
//Now you will have segue'd to C passing the string you got from a
}
}
Make sure that your segue.identifier's match what you set them in storyboard.

Related

How to simply pass numbers and equations across view controllers? [duplicate]

This question already has answers here:
Passing data between view controllers
(45 answers)
How do I pass a string or data object between two view controllers?
(2 answers)
Closed 4 years ago.
I want to have 3 View Controllers; A, B, and C. View Controller A will be where the final value gets displayed, or the Main View Controller. View Controller B and View Controller C will have simple Text Fields as inputs. The values you put into the Text Fields in View Controller B and C will be added together and shown in View Controller A. You will also need to have buttons to implement the action. How can this be done?
For instance, if the user inputs the number 2 in View Controller B and the number 3 in View Controller C text fields, then View Controller A will show the number 5.
There are multiple methods to do so
You can use delegate, notification centre etc.
try this reference
Send data back
Send Data Back
and it would be more helpful if you can share your code, what have you done so far.
First create the variable "numberOfCViewController" in ViewController B and create two variables called "numberOfCViewControllerInA" and "numberOfBViewControllerInA" in ViewController A
Then just create segues between all the controllers and simply add this function to pass the TextFields data:
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "CViewControllerToBViewController"
{
let BViewController = segue.destination as! BViewController
BViewController.numberOfCViewController = numberTextField.text!
}
}
By doing that you pass the numberTextField.text! over to the ViewController B.
All you now have to do is repeat the same techniche in the other ViewControllers until youve reached C.
Then you just simply add the two numbers and assign the result to the Label in ViewController C.
Depends on what your using:
Segue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard segue.identifier == "ViewControllerBToViewControllerC" else {
return
}
guard let viewControllerB = segue.destination as? ViewControllerB else {
return
}
viewControllerB.passedValue = <insert passed value>
}
Navigation Controller:
guard let navigationController = navigationController else {
return
}
guard let viewControllerB = UIStoryboard(name: "\(ViewControllerB.self)", bundle: nil) as? ViewControllerB else {
return
}
viewControllerB.passedValue = <insert passed value>
navigationController.pushViewController(viewControllerB, animated: true)

Using a ViewController variable in segue.destination

In the code below, I'm trying to use the variable controller to fill in the type of my destination segue at the bottom. But instead I get an error message that says controller is undeclared. It's declared right there on the second line! I can see it! I realize there are many alternatives to using segue identifiers but I'm more interested in learning why this doesn't work.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
var controller: UIViewController
switch segue.identifier {
case "ASegue":
controller = AViewController()
case "BSegue":
controller = BViewController()
case "CSegue":
controller = CViewController()
default:
controller = AViewController()
}
if let vc = segue.destination as? controller { //Use of undeclared type 'controller'
...
}
}
A cast must be to a type (literal), not a variable.
And in any case you cannot conflate all your action into a single controller variable as you seem to want to do, exactly because they are different types.
So you would simply move the cast into each case of the switch, casting to the type that you expect for that segue's destination controller, and doing the appropriate work on that controller in that case:
switch segue.identifier {
case "ASegue":
if let controller = segue.destination as? AViewController {
// do stuff
}
case "BSegue":
if let controller = segue.destination as? BViewController {
// etc.
Perhaps a slightly cleaner way of expressing this is to forget the identifier and just go for the view controller class, if each possible segue has a different view controller class:
switch segue.destination {
case let controller as AViewController:
// populate controller
case let controller as BViewController:
// populate controller
// etc.

Passing data through multiple viewcontrollers

I want to pass data from firstViewController -> secondNavigationcontroller -> secondTabBarController -> secondViewcontroller.
I can pass it to my navigationcontroller like this:
if segue.identifier == "StartMatchSegue" {
if let destination = segue.destination as? SecondNavigationController {
destination.delegate = self as? UINavigationControllerDelegate
destination.testString = "lets play"
}
}
but I cant figure out how to pass it all the way.
storyboard
You could also create a singleton which can be accessed within each view controller.
You can pass data in different ways two of them i have mentioned below.
NotitificationCenter
Closure

Variable shared between view controllers of storyboard?

My app is split into 2 storyboards: a character selection one and a main application one. When the user selects a character the app segues's to the main application, and all the views of that storyboard should now relate to the character the user selected.
I'm trying to find out the best way to share a String that will have the selected character's information between all the main application storyboard's views. Right now I'm using UserDefaults to just set a global variable:
func loadMainApp(sender: UITapGestureRecognizer) {
let currentCharcter = allCharacters[(sender.view?.tag)!]
let defaults: UserDefaults = UserDefaults.standard
defaults.setValue(currentCharacter, forKey: "CurrentCharacter")
performSegue(withIdentifier: "MainAppSegue", sender: self)
}
From there all the view controllers in the Main App storyboard can fetch the string from UserDefaults.
Is this the best way of doing such a thing or is there a better way?
The better way is to pass the character to the viewController you are segueing to, and the easiest way to do that is with prepare(for segue. If you change your performSegue call to pass the sender on by saying performSegue(withIdentifier: "MainAppSegue", sender: sender) you will be able to access that in prepare(for like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//Safely check to make sure this is the correct segue by unwrapping the sender and checking the segue identifier
if let tapGesture = sender as? UITapGestureRecognizer, let tapGestureView = sender.view, let mainViewController = segue.destination as? MainViewController, segue.identifier == "MainAppSegue" {
//Get a reference to the character that was selected
let currentCharacter = allCharacters[tapGestureView.tag]
//Pass the character to the new viewController
mainViewController.character = currentCharacter
}
}
I made a couple assumptions about the name of the viewController you are performing the segue to, and assumed it has a variable called character where you can send your character. Your new viewController now has a reference to the character.
If I understand you well. Personally I am using Singeltons for achieving Global variable between Views rather than UserDefaults
class SomeClass{
static let sharedInstance = SomeClass()
var someString = "This String is same from any class"
}
Usage inside of some function :
SomeClass.sharedInstance.someString = "Changing Global String"

How do I pass a value from my SplitView controller to a map?

So I have a SplitView controller and the cells have cities and states (ex: Dalllas, TX, etc) when I select a cell I know how to go to a detail view using a segue. But, how do I send data another UIViewController containing a map?
After I’ve created my segue my code associated with the SplitView looks like this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let cell:UITableViewCell = sender as! UITableViewCell
let destinationViewController:ViewController = segue.destinationViewController as! ViewController
// “cell.textLable” is where the value is passed from the SplitView
if let text = cell.textLabel!.text {
let incedent = LocationIncedent(sName: text)
destinationViewController.detailString = "Lat:" + String(stringInterpolationSegment: incedent.incLat) + " Long:" + String(stringInterpolationSegment: incedent.incLong)
DestinationViewController is where the label accepts displays the value. However, how do I get the values sent to a map instead of a label. Moreover, I need to pass latitude and longitude coordinates to a CLLocationCoordinate2D method.
Thanks
You create a property on the destinationViewController for each object you want to pass and assign this property in the segue method.
In your destinationViewController's viewDidLoad() you can user the data signed to these properties to populate a MKMapView...