How to Pass Prepareforsegue: an Object

How to pass prepareForSegue: an object

Simply grab a reference to the target view controller in prepareForSegue: method and pass any objects you need to there. Here's an example...

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:@"YOUR_SEGUE_NAME_HERE"])
{
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];

// Pass any objects to the view controller here, like...
[vc setMyObjectHere:object];
}
}

REVISION: You can also use performSegueWithIdentifier:sender: method to activate the transition to a new view based on a selection or button press.

For instance, consider I had two view controllers. The first contains three buttons and the second needs to know which of those buttons has been pressed before the transition. You could wire the buttons up to an IBAction in your code which uses performSegueWithIdentifier: method, like this...

// When any of my buttons are pressed, push the next view
- (IBAction)buttonPressed:(id)sender
{
[self performSegueWithIdentifier:@"MySegue" sender:sender];
}

// This will get called too before the view appears
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"MySegue"]) {

// Get destination view
SecondView *vc = [segue destinationViewController];

// Get button tag number (or do whatever you need to do here, based on your object
NSInteger tagIndex = [(UIButton *)sender tag];

// Pass the information to your destination view
[vc setSelectedButton:tagIndex];
}
}

EDIT: The demo application I originally attached is now six years old, so I've removed it to avoid any confusion.

Passing object with prepareForSegue Swift

You have to give the segue an identifier in the storyboard.(say mySegue)

Using Xcode 10 swift 4.x(Also works with Xcode 9 & 8 , swift 3.x)

override func prepare(for segue: UIStoryboardSegue, sender: Any?){}

Is called for all segues being called from your current UIViewController. So the identifier is to differentiate the different segues

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "mySegue" ,
let nextScene = segue.destination as? VehicleDetailsTableViewController ,
let indexPath = self.tableView.indexPathForSelectedRow {
let selectedVehicle = vehicles[indexPath.row]
nextScene.currentVehicle = selectedVehicle
}
}

If you are using Using Xcode 7, swift 2.x

Then use this code:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "mySegue" {
var nextScene = segue.destinationViewController as! VehicleDetailsTableViewController

// Pass the selected object to the new view controller.
if let indexPath = self.tableView.indexPathForSelectedRow {
let selectedVehicle = vehicles[indexPath.row]
nextScene.currentVehicle = selectedVehicle
}
}
}

Place a breakpoint after nextScene and see if it is being triggered by clicking any cell in the TableView. If it isn't then the identifier name u provided in the storyboard must be different then the one given here.

How to pass object using segue

override PrepareForSegue in your ViewController to set parameters on the destination controller. You will need to define public methods or properties on the destination controller that allow you to pass parameters:

public override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
{
if (segue.Identifier == "TaskSegue") { // set in Storyboard
var navctlr = segue.DestinationViewController as TaskDetailViewController;
if (navctlr != null) {

// some public method you create in your destination controller
navctlr.SetTask (this, item);
}
}
}

Pass data with prepareForSegue

You have correctly passed the definition as a String in the sender parameter in performSegueWithIdentifier. You just need to use its value in prepareForSegue, but first you must cast it from AnyObject? back to a String.

Your code could be something like:

class ViewController: UIViewController {
@IBAction func AbstractionBtn(sender: AnyObject) {
performSegueWithIdentifier("ShowDefinition", sender: "Abstraction")
}

@IBAction func binarySystemBtn(sender: AnyObject) {
performSegueWithIdentifier("ShowDefinition", sender: "Binary System")
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "ShowDefinition") {
if let destinationViewController = segue.destinationViewController as? EnglishViewController {
if let definition = sender as? String {
if definition == "Abstraction" {
destinationViewController.titleMsg = "Abstraction"
destinationViewController.definitionMsg = "Abstraction Definition"
} else if definition == "Binary System" {
destinationViewController.titleMsg = "Binary System"
destinationViewController.definitionMsg = "Binary System Definition"
}
}
}
}
}
}

How to Pass Variables and Objects from a Subclass via a Segue in Swift 3.0

  1. Another option is to call

    "func performSegue(withIdentifier identifier: String, sender: Any?)"

    which will trigger a segue from ViewController to
    SecondViewController. This is you like to keep the code of moving between ViewControllers in the storyboard ie, you controlled dragged from ViewController to SecondViewController to create a segue and gave it a unique id.

  2. Every UIViewController (subclass of) inherits a function

    "func prepare(for segue: UIStoryboardSegue, sender: Any?)"

    which will be called by the system, this is where you can add
    implementation to as the name suggest prepare anything needed before
    a particular segue is performed. At this time the next
    ViewController have been loaded from the Storyboard into memory (but
    have not begin to be displayed). And the "segue"* parameter of
    "prepare(for segue: UIStoryboardSegue, sender: Any?)" actually has a
    property "destination" which is actually the next ViewController.

    Be Careful though, as you may have more than 1 segue from this
    ViewController to different next ViewController.

    So "segue.destination" may not be your desired SecondViewController if
    you have more than 1 segue setup. Because the system calls
    "prepare(for segue: UIStoryboardSegue, sender: Any?)" for every
    segue leaving this current ViewController. Make sure you check
    "segue.identifier" to make sure your subsequent code are dealing
    with the same segue you think you are.

  3. Now you are finally able to do what your headline question is about.
    with a pointer to the SecondViewController you are free to set any
    property it has, which is the particular instance of your Capital
    object. To come full circle, the "sender" parameter of
    "performSegue(withIdentifier identifier: String, sender: Any?)"* and
    "prepare(for segue: UIStoryboardSegue, sender: Any?)" are actually the
    samething. So you can actually pass any object/struct you like from
    "performSegue()" to "prepare(for:)" Simply cast the sender object into the
    type you passed after confirming the "segue.identifier."


func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let capital = view.annotation as! Capital
let placeName = capital.title
let placeInfo = capital.info

// Option 1
perform segue.performSegue(withIdentifier: "SegueToSecondID", sender: capital)

//Option 2 programmatically create SecondViewController and show.
let SecondViewController = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController")
SecondViewController.capital = capital
self.show(SecondViewController!, sender: nil)
}

// If you are doing option 1
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SegueToSecondID" && sender is Capital {
let destination = segue.destination as SeconViewController
destination.capital = sender
}
}

class SecondViewController {
//........
var capital: Capital? //Up to you if you want this as an optional

}

How to use the PrepareForSegue method to transfer an object which has an unknown type in the receiving controller?

Two options:

  1. if typeOfMyStructure is created inside the first view controller declare in the second view controller

    var sentData: FirstViewController.typeOfMyStructure!
  2. Declare typeOfMyStructure outside of any view controller

Side note: Please name structs and classes with a starting capital letter

passing tapped cell data to another view via segue in Swift

Make sure that you have created your segue from the view controller object in the storyboard and not the cell; if you create the segue from the cell, then the segue will fire before didSelectRowAt is called.

Once you have set the segue correctly, you can use the sender parameter to avoid the use of the detailToSend property:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

var detailToSend: SingleRepository
if filteredResult.count > 0 {
detailToSend = filteredResult[indexPath.row]
} else {
detailToSend = finalArrayUnwrapped[indexPath.row]
}
performSegue(withIdentifier: "showDetailSegue", sender: detailToSend)
}


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? DetailViewController, let detailToSend = sender as? SingleRepository {
vc.detail = detailToSend
}
}

Pass variable returned Object via Segue depending on which button pressed

I'll add my comment as an answer instead, to make it easier to show some code examples.

Add a property to your viewcontroller:

var selectedWorkout : FinalWorkout!

in each of your three button action methods you set this property to the workout associated with each button. So for your standard workout:

@IBAction func standardWorkoutPressed(_ sender: UIButton) {
let finalTimeForWorkout = Int(timeInputField.text!)

self.selectedWorkout = FinalWorkout(generatedWorkout: WorkoutGenerator.standardWorkout.generate(), timeForWorkout: finalTimeForWorkout!)
performSegue(withIdentifier: "goToWorkout", sender: self )
}

Finally:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToWorkout" {
let finalWorkoutTime = selectedWorkout.timeForWorkout
let finalWorkoutExercises = selectedWorkout.generatedWorkout.workoutExercises
if let destVC = segue.destination as? WorkoutController {
destVC.selectedWorkoutExerciseArray = finalWorkoutExercises
destVC.selectedWorkoutTime = finalWorkoutTime
}
}
}


Related Topics



Leave a reply



Submit