2016-02-10 7 views
20

Ich habe zwei View-Controller erstellt. Ich habe einen Übergang von der ersten zur zweiten erstellt, um Daten zu übergeben. Jetzt möchte ich Daten vom zweiten View-Controller an den ersten übergeben. Ich habe viele ähnliche Fragen gestellt und kann diese nicht umsetzen, da mir das Wissen darüber, wie die Abwicklung funktioniert, fehlt.Daten mit Abwicklungs-Segment übergeben

ViewController.swift

class ViewController: UIViewController 
{ 
    var dataRecieved: String? 
    @IBOutlet weak var labelOne: UILabel! 
    @IBAction func buttonOne(sender: UIButton) 
    { 
     performSegueWithIdentifier("viewNext", sender: self) 
    } 
    override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!) 
    { 

     var svc: viewControllerB = segue.destinationViewController as! viewControllerB 
     svc.dataPassed = labelOne.text 
    } 
} 

Dadurch werden die Daten an dataPassed in View-Controller "viewControllerB" übergeben. Angenommen, ich möchte jetzt einige Daten von viewControllerB an dataRecieved in ViewController übergeben. Wie kann ich dies tun, nur mit dem Abwickeln und nicht mit Delegate. Ich bin ziemlich neu zu schnell, würde eine ausführliche Erklärung schätzen.

+0

Implementieren Sie einfach 'prepareForSegue' in Ihrem Abwicklungsansicht-Controller und greifen Sie auf den' destinationViewController' zu, bei dem es sich um den View-Controller handelt, auf den Sie zugreifen möchten. Wahrscheinlich möchten Sie den Abwicklungsbereich und die Kennung in Ihrem Storyboard angeben. – Paulw11

+0

Es wird ein Fehler ausgegeben "hat keinen Übergang mit dem Bezeichner 'btnSubmitSegue' '". Ich habe die Segmentkennung im View-Controller hinzugefügt. Ich verwende nur einen Übergang, um beide View-Controller zu verbinden. Ich glaube, dass sich above segue einfach auf den vorherigen View-Controller zurückzieht, ohne dass zusätzliche Schritte erforderlich sind. Können Sie das bitte im Detail erklären?Irgendein Code würde geschätzt werden :) – ebby94

+0

Sie erstellen die Abwicklungssequenz wie üblich - ziehen Sie auf das 'Exit'-Symbol in der Szene. Im Objektinspektor auf der linken Seite sehen Sie jetzt den Abwicklungsbereich, der unter den Symbolen für View-Controller, First Responder und Exit aufgelistet ist. Sie können auf den Abwicklungsabschnitt klicken und im Inspektor auf der rechten Seite eine Kennung eingeben. – Paulw11

Antwort

43

Øyvind Hauge schlug mich auf die gleiche Lösung Methode, aber wie ich schon mit einer detaillierteren Antwort begonnen hatte, werde ich es auch hinzufügen.


Lassen Sie uns sagen, dass Ihre beiden View-Controller werden wie folgt benannt:

Punkt
  • Master/Eintrag: ViewController(vcA)
  • Secondary Ansicht: ViewControllerB(vcB)

Sie richten die segue von (vcA) -> (vcB) wie Sie in Ihrem Beispiel

getan haben
/* 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 
    } 
} 

Der etwas heikel Schritt ist weiter, dass mit dieser Methode, die segue verwendet für Daten zurück von(vcB)-(vcA) ist auch zur Quelle des (vcA) hinzugefügt, als @IBAction Methode übergeben (eher als, wie möglicherweise zu erwarten war, zu der Quelle von (vcB) hinzugefügt).

/* in ViewController.swift */ 

// ... 

// segue ViewControllerB -> ViewController 
@IBAction func unwindToThisView(sender: UIStoryboardSegue) { 
    if let sourceViewController = sender.sourceViewController as? ViewControllerB { 
     dataRecieved = sourceViewController.dataPassed 
    } 
} 

Sie danach eine Verbindung beispielsweise einen Knopf in (vcB) dieser Abroller Aktion in (vcA) über die manuelle Exit segue in (vcB):

enter image description here

Im Folgenden ein vollständiges Beispiel folgt aus (vcA) zum Text der Weitergabe (vcB); (möglicherweise) Ändern dieses Textes über eine UITextField, schließlich den (möglicherweise) modifizierten Text an (vcA).


(vcA) Quelle:

/* 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) Quelle (beachten Sie, dass die UITextFieldDelegate Delegierten hier nur für „lokal“ verwendet wird, um den Wert der dataPassed Eigenschaft mutiert, die zu (vcA) und zugewiesen zurückgegeben werden dataRecieved Eigenschaft der letzteren)

/* 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 
    } 
} 

Beispielausführung:

enter image description here

+0

Vielen Dank für die ausführliche Erklärung! Das hat mir geholfen, besser zu verstehen :) – ebby94

+0

Vielleicht ist es direkt vor mir, aber was ist 'newValue' in 'setzen { labelOne.text = newValue }' –

+0

@DarkhorseFantasySports keine Sorgen: Es ist ein Standardname für den neuen Wert zu sein set: _ "Wenn Sie einen' willSet'-Beobachter implementieren, wird ihm der neue Eigenschaftswert als konstanter Parameter übergeben. Sie können einen Namen für diesen Parameter als Teil Ihrer 'willSet'-Implementierung angeben. Wenn Sie den Parameternamen nicht schreiben und Klammern in Ihrer Implementierung, der Parameter wird mit einem Standardparameternamen 'newValue' zur Verfügung gestellt." _ - Aus [Swift Language Guide - Eigenschaften] (https://developer.apple.com/library/content/documentation/ Swift/Konzeptionelle/Swift_Programming_Language/Properties.html). – dfri

7

Dies ist, wie ich es tun würde:

  1. einen Auslass in View-Controller 1, wie folgt erstellen:

    @IBAction func unwindToViewController1(segue: UIStoryboardSegue) { 
    
        let foo = segue.sourceViewController.foo 
    
        // TODO: Use foo in view controller 1 
    } 
    
  2. Connect View-Controller 2 (die vc Sie abwickelt werden) wie unten gezeigt. Ziehen Sie von dem gelben Kreis in VC2 zu "Exit". Die IBAction vom View Controller 1 sollte erscheinen. Wählen Sie es aus. enter image description here

  3. Nun, wenn Sie von View-Controller 2, die unwindToViewController1: Verfahren in View-Controller abschalten 1 wird aufgerufen.

  4. Hier erhalten Sie die gewünschte Eigenschaft von View Controller 2. Beachten Sie, dass Sie die segue.sourceViewController in Ihre benutzerdefinierte View Controller-Unterklasse umwandeln müssen, um die richtige Eigenschaft zu erhalten.

+0

Danke! Das hat meine Frage beantwortet :) – ebby94

+0

Froh, dass es geklappt hat –

0

Wenn Ihre App iOS 9+ unterstützt, können Sie Daten fast die gleichen wie prepareForSegue geben, verwenden UIStoryboardUnwindSegueSource, die eine sender Eigenschaft hat, die genau das gleiche wie die die sender Eigenschaft in prepare(for segue: UIStoryboardSegue, sender: Any?).

Wie man es verwendet:

  1. eine Methode unwindTo erstellen.

Hinweis: die unwindTo Methode Anschließen ist das gleiche wie @ Øyvind Hauge und @dfri erklärt in ihren Antworten.

  1. Innerhalb der Ansicht Controller, den Sie entspannen möchten, überschreiben die Methode canPerformUnwindSegueAction(_:from:withSender:)
  2. Innerhalb dieser Methode überprüfen, ob der Typ fromViewController der Typ Sie von
  3. kamen Wenn es ist, werfen die sender Eigenschaft auf den Typ, den Sie
  4. Else, return false

-Code Schnipsel (Swift 4.0) wahr gesendet und zurück:

@IBAction func unwindToMyFirstViewController(segue: UIStoryboardSegue) {} 

override func canPerformUnwindSegueAction(_ action: Selector, from fromViewController: UIViewController, withSender sender: Any) -> Bool { 
    if fromViewController is MyCustomViewController, 
     let customType = sender as? MyCustomType { 
     return true 
    } 
    return false 
} 
Verwandte Themen