Accéder à l'instance D'un Viewcontroller à partir d'une autre dans swift

j'essaie de transférer des données d'un contrôleur de vue à l'étiquette d'un autre.

Comment puis-je appeler l'instance du contrôleur de vue à partir du code de L'autre contrôleur de vue? Je travaille avec storyboards donc je n'ai jamais créé une instance des contrôleurs de vue dans le code? Les instances sont-elles créées automatiquement? Et ce nom ont-ils?

merci de votre aide!

24
demandé sur McLawrence 2014-08-08 17:06:18

3 réponses

1. Si le contrôleur de vue contenant le textfield peut appeler (avec une séquence) le contrôleur de vue contenant l'étiquette...

Ajouter un nouveau fichier de classe Cocoa Touch dans votre projet, nommez-le FirstViewController et définissez le code suivant:

import UIKit

class FirstViewController: UIViewController {

    @IBOutlet weak var textField: UITextField! // FIXME: link this to the UITextField in the Storyboard!!!

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        let controller = segue.destinationViewController as! SecondViewController
        controller.text = textField.text
    }

}

Ajouter un nouveau fichier de classe Cocoa Touch dans votre projet, nommez-le SecondViewController et définissez le code suivant:

import UIKit

class SecondViewController: UIViewController {

    var text: String?
    @IBOutlet weak var label: UILabel! // FIXME: link this to the UILabel in the Storyboard!!!

    override func viewDidLoad() {
        super.viewDidLoad()

        label.text = text
    }

}

dans le Storyboard, intégrer le contrôleur de première vue dans un UINavigationController. Lien vers la première vue contrôleur à la seconde avec un UIButton et UIBarButtonItem. Définissez le nom du contrôleur de première vue à FirstViewController et le nom de la seconde vue-contrôleur SecondViewController. Créer un UITextField dans le contrôleur de première vue. Créer un UILabel dans le contrôleur de deuxième vue. Liez le champ de texte et le label à leurs déclarations respectives dans FirstViewController et SecondViewController.


2. Si le contrôleur de vue contenant l'étiquette peut appeler (avec une séquence) le contrôleur de vue contenant le textfield...

Ici, c'est un parfait protocole/délégué cas. Vous pouvez trouver beaucoup de choses sur StackOverflow traiter cette question. Cependant, voici un exemple grossier.

Ajouter un nouveau fichier de classe Cocoa Touch dans votre projet, nommez-le FirstViewController et définissez le code suivant:

import UIKit

class FirstViewController: UIViewController, DetailsDelegate {

    @IBOutlet weak var label: UILabel! // FIXME: link this to the UILabel in the Storyboard

    func updateLabel(withString string: String?) {
        label.text = string
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        let controller = segue.destinationViewController as! SecondViewController
        controller.delegate = self
    }

}

Ajouter un nouveau fichier Cocoa / Cocoa Touch class dans votre projet, name it SecondViewController et définissez le code suivant:

import UIKit

protocol DetailsDelegate: class {
    func updateLabel(withString string: String?)
}

class SecondViewController: UIViewController {

    weak var delegate: DetailsDelegate?
    @IBOutlet weak var textField: UITextField! // FIXME: link this to the UITextField in the Storyboard

    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)

        delegate?.updateLabel(withString: textField.text)
    }

}

dans le Storyboard, intégrer le premier contrôleur de vue dans un UINavigationController. Relier le premier contrôleur de vue au second avec un UIButton et UIBarButtonItem. Définissez le nom du contrôleur de première vue à FirstViewController et le nom de la seconde vue-contrôleur SecondViewController. Créer un UILabel dans le contrôleur de première vue. Créer un UITextField dans le contrôleur de deuxième vue. Liez le champ de texte et le label à leurs déclarations respectives dans FirstViewController et SecondViewController.

17
répondu Imanou Petit 2018-03-08 21:42:36

Imanou Petit et Oscar Swanros ont déjà répondu correctement. Cependant il y a une alternative qui est plutôt "hacky" que j'ai dû utiliser pour transférer des données entre 2 contrôleurs de vue sans qu'une séquence les connecte.

pour obtenir le contrôleur de vue root de votre application, vous pouvez faire:

UIApplication.sharedApplication().windows[0].rootViewController

de là, vous pouvez obtenir n'importe quel contrôleur de vue que vous voulez. Par exemple, si vous voulez le second contrôleur de vue enfant du contrôleur de vue racine, alors vous devriez faire:

let viewController = UIApplication.sharedApplication().windows[0].rootViewController?.childViewControllers[1] as? YourViewController
viewController?.yourProperty = newValue

Gardez à l'esprit que cette approche est plutôt "hacky" et viole probablement les meilleures pratiques de codage.

8
répondu João Neves 2016-03-01 19:50:21

vous devez créer une séquence entre les contrôleurs de vue:

  1. sur votre Storyboard, sélectionnez ViewController A.
  2. en tenant le Control, cliquez sur ViewController A, faites glisser la ligne bleue ViewController B. Si ViewController A est intégré dans un NavigationController, sélectionnez "afficher" dans le menu qui apparaît lorsque vous laissez aller. Sinon, sélectionnez " présenter modalement."
  3. sélectionnez la séquence sur votre Storyboard, et sur le Panneau Utilities, allez à L'attribut Inspector et assignez un Identifiant pour votre séquence (par exemple: "DetailSegue").

Maintenant, quand vous le voulez pour déclencher la séquence sur ViewController A, il vous suffit d'appeler (peut-être sur le robinet d'un bouton):

@IBAction func buttonTapped() {
    self.performSegueWithIdentifier("DetailSegue", sender: self)
}

pour passer une valeur à ViewController B, Outrepasser le prepareForSegue:sender méthode ViewController A:

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
    if segue.identifier == "DetailSegue" {
        var viewControllerB = segue.destinationViewController as ViewControllerB
        viewControllerB.text = self.textField.text
    }
}

Assez simple.

notez que pour que cela fonctionne, votre ViewController B classe devrait ressembler à quelque chose comme ceci:

class ViewControllerB: UIViewController {
    ver label = UILabel(...)
    var text: String? 

    override func viewDidLoad() {
        super.viewDidLoad()

        label.text = text!
    }
}

J'espère que cela vous aidera.

5
répondu Oscar Swanros 2014-08-08 14:20:57