360 Stimmen

So übergeben Sie prepareForSegue: ein Objekt

Ich habe viele Annotationen in einer Kartenansicht (mit rightCalloutAccessory Tasten). Die Schaltfläche führt eine Überblendung von dieser mapview zu einer tableview . Ich möchte die tableview ein anderes Objekt (das Daten enthält), je nachdem, welche Schaltfläche des Aufrufs angeklickt wurde.

Zum Beispiel: (frei erfunden)

  • annotation1 (Austin) -> pass data obj 1 (relevant für Austin)
  • annotation2 (Dallas) -> pass data obj 2 (relevant für Dallas)
  • annotation3 (Houston) -> pass data obj 3 und so weiter... (Sie verstehen schon Idee)

Ich kann erkennen, welche Schaltfläche des Aufrufs angeklickt wurde.

Ich benutze prepareForSegue : Übergabe des Datenobjekts an das Ziel ViewController . Da ich diesen Aufruf nicht dazu bringen kann, ein zusätzliches Argument für das benötigte Datenobjekt anzunehmen, welche eleganten Möglichkeiten gibt es, denselben Effekt zu erzielen (dynamisches Datenobjekt)?

Für jeden Tipp wären wir dankbar.

673voto

Simon Punkte 8981

Nehmen Sie einfach einen Verweis auf den Ziel-View-Controller in prepareForSegue: Methode und übergeben Sie dort alle Objekte, die Sie benötigen. Hier ist ein Beispiel...

- (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: Sie können auch verwenden performSegueWithIdentifier:sender: Methode, um den Übergang zu einer neuen Ansicht aufgrund einer Auswahl oder eines Tastendrucks zu aktivieren.

Nehmen wir zum Beispiel an, ich hätte zwei View-Controller. Der erste enthält drei Schaltflächen und der zweite muss wissen, welche dieser Schaltflächen vor dem Übergang gedrückt wurde. Man könnte die Schaltflächen mit einem IBAction in Ihrem Code, der Folgendes verwendet performSegueWithIdentifier: Methode, etwa so...

// 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: Die ursprünglich beigefügte Demo-Anwendung ist inzwischen sechs Jahre alt, daher habe ich sie entfernt, um Verwirrung zu vermeiden.

82voto

TotoroTotoro Punkte 17255

Manchmal ist es hilfreich, eine Kompilierzeit-Abhängigkeit zwischen zwei View Controllern zu vermeiden. Hier ist, wie Sie es tun können, ohne sich um den Typ des Ziel-Viewcontrollers zu kümmern:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.destinationViewController respondsToSelector:@selector(setMyData:)]) {
        [segue.destinationViewController performSelector:@selector(setMyData:) 
                                              withObject:myData];
    } 
}

Solange Ihr Ziel-View-Controller also eine öffentliche Eigenschaft deklariert, z.B.:

@property (nonatomic, strong) MyData *myData;

können Sie diese Eigenschaft im vorherigen View-Controller wie oben beschrieben einstellen.

23voto

Remy Cilia Punkte 2473

In Swift 4.2 würde ich etwas Ähnliches tun:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let yourVC = segue.destination as? YourViewController {
        yourVC.yourData = self.someData
    }
}

16voto

neoneye Punkte 47046

Ich habe eine Absenderklasse wie diese

@class MyEntry;

@interface MySenderEntry : NSObject
@property (strong, nonatomic) MyEntry *entry;
@end

@implementation MySenderEntry
@end

Ich verwende diese Absenderklasse für die Übergabe von Objekten an prepareForSeque:sender:

-(void)didSelectItemAtIndexPath:(NSIndexPath*)indexPath
{
    MySenderEntry *sender = [MySenderEntry new];
    sender.entry = [_entries objectAtIndex:indexPath.row];
    [self performSegueWithIdentifier:SEGUE_IDENTIFIER_SHOW_ENTRY sender:sender];
}

-(void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:SEGUE_IDENTIFIER_SHOW_ENTRY]) {
        NSAssert([sender isKindOfClass:[MySenderEntry class]], @"MySenderEntry");
        MySenderEntry *senderEntry = (MySenderEntry*)sender;
        MyEntry *entry = senderEntry.entry;
        NSParameterAssert(entry);

        [segue destinationViewController].delegate = self;
        [segue destinationViewController].entry = entry;
        return;
    }

    if ([[segue identifier] isEqualToString:SEGUE_IDENTIFIER_HISTORY]) {
        // ...
        return;
    }

    if ([[segue identifier] isEqualToString:SEGUE_IDENTIFIER_FAVORITE]) {
        // ...
        return;
    }
}

16voto

Suragch Punkte 420096

Ich stieß auf diese Frage, als ich versuchte zu lernen, wie man Daten von einem View Controller an einen anderen weitergibt. Ich brauche etwas Visuelles, das mir beim Lernen hilft, also ist diese Antwort eine Ergänzung zu den anderen, die bereits hier stehen. Es ist ein wenig mehr allgemein als die ursprüngliche Frage, aber es kann angepasst werden, um zu arbeiten.

Dieses einfache Beispiel funktioniert folgendermaßen:

enter image description here

Die Idee ist, eine Zeichenkette aus dem Textfeld im ersten View Controller an das Label im zweiten View Controller zu übergeben.

Erster View Controller

import UIKit

class FirstViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!

    // This function is called before the segue
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        // get a reference to the second view controller
        let secondViewController = segue.destinationViewController as! SecondViewController

        // set a variable in the second view controller with the String to pass
        secondViewController.receivedString = textField.text!
    }

}

Zweiter View Controller

import UIKit

class SecondViewController: UIViewController {

    @IBOutlet weak var label: UILabel!

    // This variable will hold the data being passed from the First View Controller
    var receivedString = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        // Used the text from the First View Controller to set the label
        label.text = receivedString
    }

}

Denken Sie daran

  • Die Überleitung erfolgt durch control Klicken Sie auf die Schaltfläche und ziehen Sie sie in den zweiten View Controller.
  • Verbinden Sie die Steckdosen für die UITextField und die UILabel .
  • Setzen Sie den ersten und zweiten View-Controller auf die entsprechenden Swift-Dateien in IB.

Source

Wie man Daten über Segue (Swift) sendet (YouTube-Anleitung)

Siehe auch

Ansicht Steuergeräte: Datenweitergabe und Datenrückgabe (ausführlichere Antwort)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X