vistas pasar entre datos ios swift segue unwind-segue

ios - entre - Pasar datos con desenrollar segue



pasar datos entre view controllers swift (3)

Øyvind Hauge me superó con el mismo método de solución, pero como ya había comenzado con una respuesta más detallada, también la agregaré.

Digamos que sus dos controladores de vista se nombran de la siguiente manera:

  • Maestro / punto de entrada: ViewController (vcA)
  • Vista secundaria: ViewControllerB (vcB)

Configura el segue desde (vcA) -> (vcB) como lo ha hecho en su ejemplo

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

El siguiente paso un tanto complicado es que, utilizando este método, el segmento utilizado para pasar datos de (vcB) a (vcA) también se agrega a la fuente de (vcA) , como un método @IBAction (en lugar de, como podría ser posible se espera, agregado a la fuente de (vcB) ).

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

Posteriormente, conecte, digamos, un botón en (vcB) a esta acción de desenrollado en (vcA) través del manual Exit segue en (vcB) :

A continuación sigue un ejemplo completo de pasar texto de (vcA) a (vcB) ; (posiblemente) modificando ese texto a través de un UITextField , finalmente devolviendo el texto (posiblemente) modificado a (vcA) .

(vcA) fuente:

/* 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) fuente (tenga en cuenta que el delegado UITextFieldDelegate aquí solo se usa para mutar "localmente" el valor de la propiedad dataPassed , que se devolverá a (vcA) y se asignará a la propiedad dataRecieved de este último)

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

Ejecución de ejemplo:

Creé dos controladores de vista. Creé un segue del primero al segundo para pasar datos. Ahora quiero pasar datos del segundo controlador de vista al primero. Revisé muchas preguntas similares y no puedo implementarlas, ya que me falta el conocimiento sobre cómo funciona el desenrollado.

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

Esto pasará los datos a dataPassed en el controlador de vista "viewControllerB". Digamos, ahora quiero pasar algunos datos de viewControllerB a dataRecieved en ViewController. ¿Cómo puedo hacer esto con solo desconectar segue y no usando delegado? Soy bastante nuevo en Swift, agradecería una explicación detallada.


Así es como lo haría:

  1. Cree una salida en el controlador de vista 1, así:

    @IBAction func unwindToViewController1(segue: UIStoryboardSegue) { let foo = segue.sourceViewController.foo // TODO: Use foo in view controller 1 }

  2. Conecte el controlador de vista 2 (el vc del que se está desenrollando) como se muestra a continuación. Arrastre desde el círculo amarillo en vc2 hasta ''Salir''. El IBAction del controlador de vista 1 debería aparecer. Seleccionarlo

  3. Ahora, cada vez que se desconecte del controlador de vista 2, se unwindToViewController1: método unwindToViewController1: en el controlador de vista 1.

  4. Aquí es donde recuperará la propiedad que desea del controlador de vista 2. Tenga en cuenta que necesita convertir el segue.sourceViewController en su subclase de controlador de vista personalizado para obtener la propiedad correcta.


Si su aplicación es compatible con iOS 9+, puede pasar datos casi de la misma manera que prepareForSegue, use UIStoryboardUnwindSegueSource que tiene una propiedad del sender que es exactamente la misma que la propiedad del sender en preparación (por ejemplo: UIStoryboardSegue, remitente: ¿Cualquiera?) .

Cómo usarlo:

  1. Crea un método unwindTo.

Nota: Conectar el método unwindTo es lo mismo que @ Øyvind Hauge y @dfri explicados en sus respuestas.

  1. Dentro del controlador de vista en el que desea relajarse, anule el método canPerformUnwindSegueAction(_:from:withSender:)
  2. Dentro de este método, verifique si el tipo fromViewController es el tipo del que provenía
  3. Si es así, convierta la propiedad del sender al tipo que envió y devuelva verdadero
  4. De lo contrario, devuelve falso

Recorte de código (Swift 4.0):

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