wake-up-neo.com

So übergeben Sie prepareForSegue: ein Objekt

Ich habe viele Anmerkungen in einer Kartenansicht (mit den Schaltflächen rightCalloutAccessory). Die Schaltfläche führt einen Übergang von mapview zu tableview durch. Ich möchte dem tableview ein anderes Objekt (das Daten enthält) übergeben, je nachdem, auf welche Callout-Schaltfläche geklickt wurde.

Zum Beispiel: (total 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 bekommen die Idee)

Ich kann feststellen, auf welche Callout-Schaltfläche geklickt wurde.

Ich benutze prepareForSegue: um das Datenobjekt an das Ziel ViewController zu übergeben. Da dieser Aufruf kein zusätzliches Argument für das von mir benötigte Datenobjekt enthalten kann, gibt es einige elegante Möglichkeiten, um denselben Effekt zu erzielen (dynamisches Datenobjekt).

Jeder Tipp wäre willkommen.

356
chizzle

Greifen Sie einfach auf einen Verweis auf den Zielansichts-Controller in der prepareForSegue: -Methode zu 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 die performSegueWithIdentifier:sender: -Methode verwenden, um den Übergang zu einer neuen Ansicht basierend auf einer Auswahl oder einem Tastendruck zu aktivieren.

Stellen Sie sich zum Beispiel vor, ich hätte zwei View-Controller. Die erste enthält drei Schaltflächen, und die zweite muss wissen, welche dieser Schaltflächen vor dem Übergang gedrückt wurde. Sie können die Tasten mit einer IBAction in Ihrem Code verbinden, die die performSegueWithIdentifier: -Methode verwendet, wie folgt ...

// 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];
    }
}

BEARBEITEN: Die Demo-Anwendung, die ich ursprünglich angehängt habe, ist jetzt sechs Jahre alt, daher habe ich sie entfernt, um Verwirrung zu vermeiden.

672
Simon

Manchmal ist es hilfreich, das Erstellen einer Kompilierungszeitabhängigkeit zwischen zwei Ansichtscontrollern zu vermeiden. So können Sie es tun, ohne sich um den Typ des Zielansichts-Controllers zu kümmern:

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

So lange Ihr Zielansichts-Controller eine öffentliche Eigenschaft deklariert, z.

@property (nonatomic, strong) MyData *myData;

sie können diese Eigenschaft im vorherigen Ansichtscontroller wie oben beschrieben festlegen.

82
Macondo2Seattle

In Swift 4.2 würde ich so etwas machen:

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

Ich habe eine Absenderklasse, so

@class MyEntry;

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

@implementation MySenderEntry
@end

Ich benutze diese Absenderklasse um Objekte an prepareForSeque:sender: zu übergeben

-(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;
    }
}
16
neoneye

Ich bin auf diese Frage gestoßen, als ich lernen wollte, wie Daten von einem View Controller zu einem anderen übertragen werden. Ich brauche jedoch etwas Visuelles, um es zu lernen, daher ist diese Antwort eine Ergänzung zu den anderen hier. Es ist etwas allgemeiner als die ursprüngliche Frage, kann aber an die Arbeit angepasst werden.

Dieses grundlegende Beispiel funktioniert folgendermaßen:

enter image description here

Die Idee ist, eine Zeichenfolge aus dem Textfeld im First View Controller an die Beschriftung im Second View Controller zu übergeben.

First 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!
    }

}

Second 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
    }

}

Erinnere dich an

  • Machen Sie den Übergang durch control Klicken Sie auf die Schaltfläche und ziehen Sie sie auf den Second View Controller.
  • Schließen Sie die Steckdosen für UITextField und UILabel an.
  • Setzen Sie den ersten und den zweiten View Controller auf die entsprechenden Swift Dateien in IB.

Quelle

So senden Sie Daten über segue (Swift) (YouTube-Tutorial)

Siehe auch

View Controllers: Daten weitergeben und Daten zurückgeben (vollständigere Antwort)

14
Suragch

Für Swift benutze dies,

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    var segueID = segue.identifier

    if(segueID! == "yourSegueName"){

        var yourVC:YourViewController = segue.destinationViewController as YourViewController

        yourVC.objectOnYourVC = setObjectValueHere!

    }
}
5
Zaid Pathan

Ich habe eine Bibliothek mit einer Kategorie in UIViewController implementiert, die diesen Vorgang vereinfacht. Grundsätzlich legen Sie die zu übergebenden Parameter in einem NSDictionary fest, das dem UI-Element zugeordnet ist, das die Übergabe vornimmt. Es funktioniert auch mit manuellen Segmenten.

Zum Beispiel können Sie tun

[self performSegueWithIdentifier:@"yourIdentifier" parameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];

für eine manuelle Überblendung oder erstellen Sie eine Schaltfläche mit einer Überblendung und verwenden Sie

[button setSegueParameters:@{@"customParam1":customValue1, @"customValue2":customValue2}];

Wenn der Zielansichts-Controller nicht mit der Schlüsselwertcodierung für einen Schlüssel kompatibel ist, geschieht nichts. Es funktioniert auch mit Schlüsselwerten (nützlich für das Abwickeln von Abschnitten). Schau es dir hier an https://github.com/stefanomondino/SMQuickSegue

4
Stefano Mondino

Meine Lösung ist ähnlich.

// In destination class: 
var AddressString:String = String()

// In segue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
   if (segue.identifier == "seguetobiddetailpagefromleadbidder")
    {
        let secondViewController = segue.destinationViewController as! BidDetailPage
        secondViewController.AddressString = pr.address as String
    }
}
2
A.G

Verwenden Sie einfach diese Funktion.

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let index = CategorytableView.indexPathForSelectedRow
    let indexNumber = index?.row
    let VC = segue.destination as! DestinationViewController
   VC.value = self.data

}
1
Parth Barot

Ich habe diese Lösung verwendet, um den Aufruf des Segues und die Datenkommunikation in derselben Funktion zu halten:

private var segueCompletion : ((UIStoryboardSegue, Any?) -> Void)?

func performSegue(withIdentifier identifier: String, sender: Any?, completion: @escaping (UIStoryboardSegue, Any?) -> Void) {
    self.segueCompletion = completion;
    self.performSegue(withIdentifier: identifier, sender: sender);
    self.segueCompletion = nil
}

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

Ein Anwendungsfall wäre etwa:

func showData(id : Int){
    someService.loadSomeData(id: id) {
        data in
        self.performSegue(withIdentifier: "showData", sender: self) {
            storyboard, sender in
            let dataView = storyboard.destination as! DataView
            dataView.data = data
        }
    }
}

Dies scheint für mich zu funktionieren, aber ich bin nicht zu 100% sicher, dass die Funktionen "Ausführen" und "Vorbereiten" immer auf demselben Thread ausgeführt werden.

0
dannrob