Swift 5
Eh bien, la réponse de Matt Price convient parfaitement pour transmettre des données, mais je vais les réécrire, dans la dernière version de Swift, car je crois que les nouveaux programmeurs trouvent difficile de quitter en raison de la nouvelle syntaxe et des nouvelles méthodes / cadres, car la publication d'origine est en Objective-C.
Il existe plusieurs options pour transmettre des données entre les contrôleurs de vue.
- Utilisation de Navigation Controller Push
- Utilisation de Segue
- Utilisation de Delegate
- Utilisation de Notification Observer
- Utilisation de Block
Je vais réécrire sa logique dans Swift avec le dernier framework iOS
Transmission de données via la navigation du contrôleur de navigation : de ViewControllerA à ViewControllerB
Étape 1. Déclarez la variable dans ViewControllerB
var isSomethingEnabled = false
Étape 2. Imprimer la variable dans la méthode ViewDidLoad de ViewControllerB
override func viewDidLoad() {
super.viewDidLoad()
//Print value received through segue, navigation push
print("Value of 'isSomethingEnabled' from ViewControllerA : ", isSomethingEnabled)
}
Étape 3. Dans ViewControllerA Pass Data tout en poussant à travers le contrôleur de navigation
if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
viewControllerB.isSomethingEnabled = true
if let navigator = navigationController {
navigator.pushViewController(viewControllerB, animated: true)
}
}
Voici donc le code complet pour:
ViewControllerA
import UIKit
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK:Passing Data through Navigation PushViewController
@IBAction func goToViewControllerB(_ sender: Any) {
if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
viewControllerB.isSomethingEnabled = true
if let navigator = navigationController {
navigator.pushViewController(viewControllerB, animated: true)
}
}
}
}
ViewControllerB
import UIKit
class ViewControllerB: UIViewController {
//MARK: - Variable for Passing Data through Navigation push
var isSomethingEnabled = false
override func viewDidLoad() {
super.viewDidLoad()
//Print value received through navigation push
print("Value of 'isSomethingEnabled' from ViewControllerA : ", isSomethingEnabled)
}
}
Transmission de données via Segue : de ViewControllerA à ViewControllerB
Étape 1. Créez Segue de ViewControllerA à ViewControllerB et donnez Identifier = showDetailSegue dans Storyboard comme indiqué ci-dessous
Étape 2. Dans ViewControllerB, déclarez un isSomethingEnabled viable nommé et imprimer sa valeur.
Étape 3. Dans ViewControllerA, la valeur de isSomethingEnabled lors de la transmission de Segue
Voici donc le code complet pour:
ViewControllerA
import UIKit
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK: - - Passing Data through Segue - -
@IBAction func goToViewControllerBUsingSegue(_ sender: Any) {
performSegue(withIdentifier: "showDetailSegue", sender: nil)
}
//Segue Delegate Method
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "showDetailSegue") {
let controller = segue.destination as? ViewControllerB
controller?.isSomethingEnabled = true//passing data
}
}
}
ViewControllerB
import UIKit
class ViewControllerB: UIViewController {
var isSomethingEnabled = false
override func viewDidLoad() {
super.viewDidLoad()
//Print value received through segue
print("Value of 'isSomethingEnabled' from ViewControllerA : ", isSomethingEnabled)
}
}
Transmission de données via le délégué : de ViewControllerB à ViewControllerA
Étape 1. Déclarez le protocole ViewControllerBDelegate dans le fichier ViewControllerB mais en dehors de la classe
protocol ViewControllerBDelegate: NSObjectProtocol {
// Classes that adopt this protocol MUST define
// this method -- and hopefully do something in
// that definition.
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?)
}
Étape 2. Déclarez l'instance de variable Délégué dans ViewControllerB
var delegate: ViewControllerBDelegate?
Étape 3. Envoyer des données pour le délégué à l'intérieur de la méthode viewDidLoad de ViewControllerB
delegate?.addItemViewController(self, didFinishEnteringItem: "Data for ViewControllerA")
Étape 4. Confirmez ViewControllerBDelegate dans ViewControllerA
class ViewControllerA: UIViewController, ViewControllerBDelegate {
// to do
}
Étape 5. Confirmez que vous implémenterez délégué dans ViewControllerA
if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
viewControllerB.delegate = self//confirming delegate
if let navigator = navigationController {
navigator.pushViewController(viewControllerB, animated: true)
}
}
Étape 6. Implémentez la méthode déléguée pour recevoir des données dans ViewControllerA
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?) {
print("Value from ViewControllerB's Delegate", item!)
}
Voici donc le code complet pour:
ViewControllerA
import UIKit
class ViewControllerA: UIViewController, ViewControllerBDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
//Delegate method
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?) {
print("Value from ViewControllerB's Delegate", item!)
}
@IBAction func goToViewControllerForDelegate(_ sender: Any) {
if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
viewControllerB.delegate = self
if let navigator = navigationController {
navigator.pushViewController(viewControllerB, animated: true)
}
}
}
}
ViewControllerB
import UIKit
//Protocol decleare
protocol ViewControllerBDelegate: NSObjectProtocol {
// Classes that adopt this protocol MUST define
// this method -- and hopefully do something in
// that definition.
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?)
}
class ViewControllerB: UIViewController {
var delegate: ViewControllerBDelegate?
override func viewDidLoad() {
super.viewDidLoad()
//MARK: - - - - Set Data for Passing Data through Delegate - - - - - -
delegate?.addItemViewController(self, didFinishEnteringItem: "Data for ViewControllerA")
}
}
Transmission de données via Notification Observer : de ViewControllerB à ViewControllerA
Étape 1. Définir et publier des données dans Notification Observer dans ViewControllerB
let objToBeSent = "Test Message from Notification"
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: objToBeSent)
Étape 2. Ajouter un observateur de notifications dans ViewControllerA
NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
Étape 3. Recevoir la valeur des données de notification dans ViewControllerA
@objc func methodOfReceivedNotification(notification: Notification) {
print("Value of notification : ", notification.object ?? "")
}
Voici donc le code complet pour:
ViewControllerA
import UIKit
class ViewControllerA: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
// add observer in controller(s) where you want to receive data
NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
}
//MARK: Method for receiving Data through Post Notification
@objc func methodOfReceivedNotification(notification: Notification) {
print("Value of notification : ", notification.object ?? "")
}
}
ViewControllerB
import UIKit
class ViewControllerB: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//MARK:Set data for Passing Data through Post Notification
let objToBeSent = "Test Message from Notification"
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: objToBeSent)
}
}
Passage de données via le bloc : de ViewControllerB à ViewControllerA
Étape 1. Déclarez le bloc dans ViewControllerB
var autorisationCompletionBlock: ((Bool) -> ())? = {_ in}
Étape 2. Définissez les données en bloc dans ViewControllerB
if authorizationCompletionBlock != nil
{
authorizationCompletionBlock!(true)
}
Étape 3. Recevoir des données de bloc dans ViewControllerA
//Receiver Block
controller!.authorizationCompletionBlock = { isGranted in
print("Data received from Block is :", isGranted)
}
Voici donc le code complet pour:
ViewControllerA
import UIKit
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
//MARK:Method for receiving Data through Block
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "showDetailSegue") {
let controller = segue.destination as? ViewControllerB
controller?.isSomethingEnabled = true
//Receiver Block
controller!.authorizationCompletionBlock = { isGranted in
print("Data received from Block is :", isGranted)
}
}
}
}
ViewControllerB
import UIKit
class ViewControllerB: UIViewController {
//MARK:Variable for Passing Data through Block
var authorizationCompletionBlock:((Bool)->())? = {_ in}
override func viewDidLoad() {
super.viewDidLoad()
//MARK:Set data for Passing Data through Block
if authorizationCompletionBlock != nil
{
authorizationCompletionBlock!(true)
}
}
}
Vous pouvez trouver un exemple complet d'application sur mon GitHub Veuillez me faire savoir si vous avez des questions à ce sujet.
@class ViewControllerB;
au-dessus de la définition @protocol? Sans cela, j'obtiens une erreur "Type attendu" sur ViewControllerB dans la ligne:- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
dans la@protocol
déclaration