web-dev-qa-db-fra.com

Swift: prepareForSegue avec le contrôleur de navigation

Je développe une application iOS dans Swift.

Je souhaite envoyer des données d'une vue à une autre, à l'aide de la fonction prepareForSegue.

Cependant, ma vue cible est précédée d'un contrôleur de navigation, elle ne fonctionne donc pas.

Comment puis-je faire cela s'il vous plaît?

60
cedric petetin

Dans prepareForSegue, accédez au contrôleur de navigation cible, puis à son sommet:

let destinationNavigationController = segue.destination as! UINavigationController
let targetController = destinationNavigationController.topViewController

À partir du contrôleur cible, vous pouvez accéder à sa vue et transmettre des données.

Dans les versions anciennes - maintenant obsolètes de Swift et UIKit, le code était légèrement différent:

let destinationNavigationController = segue.destinationViewController as UINavigationController
let targetController = destinationNavigationController.topViewController
124
Wojtek Surowka

Supposons que vous souhaitiez envoyer des données de SendViewController à ReceiveViewController:

  1. Ajoutez ceci au SendViewController

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "segueShowNavigation"{
        var DestViewController = segue.destinationViewController as! UINavigationController
        let targetController = DestViewController.topViewController as! ReceiveViewController
        targetController.data = "hello from ReceiveVC !"
    }}
    
  2. Editez l'identifiant segue en "showNavigationController"

screenshot

  1. Dans votre ReceiveViewController ajouter

cette

var data : String = ""

override func viewDidLoad() {
    super.viewDidLoad()
    print("data from ReceiveViewController is \(data)")
}

Bien sûr, vous pouvez envoyer tout autre type de données (int, Bool, JSON ...)

26
mattyU

Réponse complète en utilisant optional binding and Swift 3 & 4:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let navigationVC = segue.destination as? UINavigationController, let myViewController = navigationVC.topViewController as? MyViewControllerClass {
        myViewController.yourProperty = myProperty
    }
}
16
jason z

Voici la réponse pour Swift 3:

let svc = segue.destination as? UINavigationController

let controller: MyController = svc?.topViewController as! MyController
controller.myProperty = "Hi there"
4
Ondrej Kvasnovsky

Une ligne dans Swift 3:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  if let vc = segue.destination.childViewControllers[0] as? FooController {
    vc.variable = localvariable
  }
}
3
JoeGalind

Dans Swift 5

Si vous devez non seulement passer d'un SourceViewController à un DestinationViewController intégré à un UINavigationController, mais également à un nouveau Storyboard, procédez comme suit ...

  1. Placez un objet "Référence du scénarimage" dans votre bibliothèque d'objets à côté de votre ViewController source dans Interface Builder, puis faites-y glisser une séquence (à partir d'un bouton de la vue SourceViewController, par exemple). Nommez l'identifiant de la division "ToOtherStoryboard", par exemple.

  2. Accédez à NavigationViewController et attribuez-lui un ID Storyboard à l'aide de l'inspecteur d'identité. "DestinationNavVC" ferait l'affaire.

  3. Cliquez sur l'icône de référence du Storyboard créée à l'étape 1 et, dans le champ 'ID référencé' de l'inspecteur d'attributs, entrez l'ID de Storyboard que vous avez écrit pour UINavigationController à l'étape 2. Cela crée une transition entre la source et le DestinationViewController, peu importe ce que vous écrivez. fichier source du ViewController source. Cela est dû au fait que la navigation sur un NaviationController affiche automatiquement le ViewController racine (le premier) de UINavigationController.

  4. Pour attacher des données et les envoyer aux propriétés dans DestinationViewController, vous devez écrire le code suivant dans une méthode Prepare-For-Segue dans votre fichier SourceViewController:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "ToOtherStoryboard" {
            let destinationNavVC = segue.destination as! UINavigationController
            let destinationVC = destinationNavVC.topController as!     DestinationViewController
    
            destinationVC.name = nameTextField.text // for example
            destinationVC.occupation = occupationTextField.text
        }
    }
    
  5. Dans la méthode de votre bouton IBAction Outlet utilisée pour initier la transition, vous écririez:

    performSegue(withIdentifer: "ToOtherStoryboard", sender: self)
    
0
Jack Pitts