Swift 5
Bem, a resposta de Matt Price é perfeitamente adequada para a transmissão de dados, mas eu vou reescrevê-los, na versão mais recente do Swift, porque acredito que os novos programadores acham bastante desafiador devido à nova sintaxe e métodos / estruturas, como a postagem original está no Objective-C.
Existem várias opções para passar dados entre os controladores de exibição.
- Usando o Push do Controlador de Navegação
- Usando Segue
- Usando Delegado
- Usando o Notification Observer
- Usando bloco
Vou reescrever sua lógica no Swift com o último iOS Framework
Passando dados pelo Push do controlador de navegação : do ViewControllerA para o ViewControllerB
Etapa 1. Declarar variável no ViewControllerB
var isSomethingEnabled = false
Etapa 2. Variável de impressão no método ViewControllerB 'ViewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
//Print value received through segue, navigation push
print("Value of 'isSomethingEnabled' from ViewControllerA : ", isSomethingEnabled)
}
Etapa 3. No ViewControllerA Pass Data enquanto pressiona através do Navigation Controller
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)
}
}
Então, aqui está o código completo para:
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)
}
}
Passando dados pelo segmento : de ViewControllerA para ViewControllerB
Etapa 1. Crie um Segue de ViewControllerA para ViewControllerB e forneça Identifier = showDetailSegue no Storyboard, como mostrado abaixo
Etapa 2. No ViewControllerB Declare um viável chamado isSomethingEnabled e imprima seu valor.
Etapa 3. No ViewController, o valor de um passe isSomethingEnabled ao passar Segue
Então, aqui está o código completo para:
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)
}
}
Passando dados por meio de delegado : de ViewControllerB para ViewControllerA
Etapa 1. Declarar o protocolo ViewControllerBDelegate no arquivo ViewControllerB, mas fora da 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?)
}
Etapa 2. Declare a instância da variável Delegate em ViewControllerB
var delegate: ViewControllerBDelegate?
Etapa 3. Envie dados para delegar dentro do método viewDidLoad do ViewControllerB
delegate?.addItemViewController(self, didFinishEnteringItem: "Data for ViewControllerA")
Etapa 4. Confirme o ViewControllerBDelegate no ViewControllerA
class ViewControllerA: UIViewController, ViewControllerBDelegate {
// to do
}
Etapa 5. Confirme que você implementará o delegado no 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)
}
}
Etapa 6. Implemente o método delegado para receber dados no ViewControllerA
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?) {
print("Value from ViewControllerB's Delegate", item!)
}
Então, aqui está o código completo para:
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")
}
}
Passagem de dados pelo Notification Observer : do ViewControllerB para o ViewControllerA
Etapa 1. Defina e publique dados no observador de notificações no ViewControllerB
let objToBeSent = "Test Message from Notification"
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: objToBeSent)
Etapa 2. Adicione o Notification Observer no ViewControllerA
NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
Etapa 3. Receba o valor dos dados de notificação no ViewControllerA
@objc func methodOfReceivedNotification(notification: Notification) {
print("Value of notification : ", notification.object ?? "")
}
Então, aqui está o código completo para:
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)
}
}
Passando dados pelo bloco : do ViewControllerB para o ViewControllerA
Etapa 1. Declarar o bloco no ViewControllerB
var authorCompletionBlock: ((Bool) -> ())? = {_ in}
Etapa 2. Defina os dados no bloco no ViewControllerB
if authorizationCompletionBlock != nil
{
authorizationCompletionBlock!(true)
}
Etapa 3. Receba os dados do bloco no ViewControllerA
//Receiver Block
controller!.authorizationCompletionBlock = { isGranted in
print("Data received from Block is :", isGranted)
}
Então, aqui está o código completo para:
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)
}
}
}
Você pode encontrar uma amostra completa do aplicativo no meu GitHub. Informe-me se tiver alguma dúvida sobre isso.
@class ViewControllerB;
definição acima da @protocol? Sem ele eu recebo um erro "Tipo esperado" na ViewControllerB na linha:- (void)addItemViewController:(ViewControllerB *)controller didFinishEnteringItem:(NSString *)item;
dentro da@protocol
declaração