Swift 5
Bene, la risposta di Matt Price va benissimo per il passaggio dei dati, ma ho intenzione di riscriverli, nella versione più recente di Swift, perché credo che i nuovi programmatori lo trovino molto difficile a causa della nuova sintassi e dei metodi / framework, poiché il post originale è in Objective-C.
Esistono più opzioni per il passaggio dei dati tra i controller di visualizzazione.
- Usando Push del controller di navigazione
- Usando Segue
- Utilizzo del delegato
- Utilizzo di Notification Observer
- Utilizzando Block
Riscriverò la sua logica in Swift con l'ultimo iOS Framework
Passaggio dei dati tramite il controller di navigazione Push : Da ViewControllerA a ViewControllerB
Passaggio 1. Dichiarare la variabile in ViewControllerB
var isSomethingEnabled = false
Passaggio 2. Stampa variabile nel metodo ViewDidLoad di ViewControllerB
override func viewDidLoad() {
super.viewDidLoad()
//Print value received through segue, navigation push
print("Value of 'isSomethingEnabled' from ViewControllerA : ", isSomethingEnabled)
}
Passaggio 3. In ViewControllerA Passare i dati mentre si spinge attraverso il controller di navigazione
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)
}
}
Quindi ecco il codice completo per:
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)
}
}
Passaggio dei dati attraverso Segue : da ViewControllerA a ViewControllerB
Passaggio 1. Creare Segue da ViewControllerA a ViewControllerB e fornire Identifier = showDetailSegue nello Storyboard come mostrato di seguito
Passaggio 2. In ViewControllerB Dichiarare un valido chiamato isSomethingEnabled e stamparne il valore.
Passaggio 3. In ViewController Un passaggio è il valore di Qualcosa abilitato durante il passaggio di Segue
Quindi ecco il codice completo per:
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)
}
}
Passaggio dei dati tramite delegato : da ViewControllerB a ViewControllerA
Passaggio 1. Dichiarare il protocollo ViewControllerBDelegate nel file ViewControllerB ma al di fuori della 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?)
}
Passaggio 2. Dichiara Delega dell'istanza variabile in ViewControllerB
var delegate: ViewControllerBDelegate?
Passaggio 3. Invia i dati per il delegato all'interno del metodo viewDidLoad di ViewControllerB
delegate?.addItemViewController(self, didFinishEnteringItem: "Data for ViewControllerA")
Passaggio 4. Confermare ViewControllerB Eliminare in ViewControllerA
class ViewControllerA: UIViewController, ViewControllerBDelegate {
// to do
}
Passaggio 5. Confermare che si implementerà il delegato in 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)
}
}
Passaggio 6. Implementare il metodo delegato per la ricezione di dati in ViewControllerA
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?) {
print("Value from ViewControllerB's Delegate", item!)
}
Quindi ecco il codice completo per:
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")
}
}
Passaggio dei dati tramite Notification Observer : da ViewControllerB a ViewControllerA
Passaggio 1. Impostare e pubblicare i dati nell'osservatore delle notifiche in ViewControllerB
let objToBeSent = "Test Message from Notification"
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: objToBeSent)
Passaggio 2. Aggiungi Osservatore notifiche in ViewControllerA
NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
Passaggio 3. Ricevi il valore dei dati di notifica in ViewControllerA
@objc func methodOfReceivedNotification(notification: Notification) {
print("Value of notification : ", notification.object ?? "")
}
Quindi ecco il codice completo per:
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)
}
}
Passaggio dei dati attraverso il blocco : da ViewControllerB a ViewControllerA
Passaggio 1. Dichiarare il blocco in ViewControllerB
var autorizzazioniCompletionBlock: ((Bool) -> ())? = {_ in}
Passaggio 2. Impostare i dati in blocco in ViewControllerB
if authorizationCompletionBlock != nil
{
authorizationCompletionBlock!(true)
}
Passaggio 3. Ricezione dei dati di blocco in ViewControllerA
//Receiver Block
controller!.authorizationCompletionBlock = { isGranted in
print("Data received from Block is :", isGranted)
}
Quindi ecco il codice completo per:
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)
}
}
}
Puoi trovare un'applicazione di esempio completa sul mio GitHub Per favore fatemi sapere se avete domande su questo.
@class ViewControllerB;
sopra la definizione @protocol? Senza di essa viene visualizzato l'errore "Tipo previsto" su ViewControllerB nella riga:- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
all'interno della@protocol
dichiarazione