I am using protocols and delegates to pass data from one viewController to another, but when I click send it only changes the viewController but does not pass the data.
Anyone know how to return data from ViewController B to ViewController A?
It compiles and works fine, but nothing is logged, so I don't know if it works.
// FirstViewController.swift
import Cocoa
class FirstViewController: NSViewController, DataEnteredDelegate {
@IBOutlet weak var buttonPasswordState: NSView!
@IBOutlet weak var label: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func buttonPasswordState(_ sender: Any) {
if let controller = self.storyboard?.instantiateController(withIdentifier: "SecondViewController") as? SecondViewController {
self.view.window?.contentViewController = controller
}
}
func userDidEnterInformation(info: String) {
label.stringValue = info
}
}
// SecondViewController.swift
import Cocoa
class SecondViewController: NSViewController {
@IBOutlet weak var buttonContinue: NSButton!
weak var delegate: DataEnteredDelegate? = nil
@IBOutlet weak var textField: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func buttonContinue(_ sender: Any) {
if let controller = self.storyboard?.instantiateController(withIdentifier: "FirstViewController") as? FirstViewController {
self.view.window?.contentViewController = controller
delegate?.userDidEnterInformation(info: textField.stringValue)
}
}
}
protocol DataEnteredDelegate: class {
func userDidEnterInformation(info: String)
}
CodePudding user response:
You're creating a brand new instance of SecondViewController here, that's not configured or changed before you show it:
if let controller = self.storyboard?.instantiateController(withIdentifier: "SecondViewController") as? SecondViewController {
// TODO something like controller.configureWith(dataFromFirstVC)... e.g. controller.delegate = self
self.view.window?.contentViewController = controller
}
and when you want to go back to your FirstViewController, again you new up a brand new instance of FirstViewController, you're not calling back to the same instance - that is your delegate:
if let controller = self.storyboard?.instantiateController(withIdentifier: "FirstViewController") as? FirstViewController {
self.view.window?.contentViewController = controller
// controller is not the same object as delegate
delegate?.userDidEnterInformation(info: textField.stringValue)
}
CodePudding user response:
I think this will help you.
class FirstViewController: UIViewController, DataPassProtocol {
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.asyncAfter(deadline: .now() 3) {
self.fireSecondViewController()
}
}
func fireSecondViewController() {
let secondViewController = SecondViewController()
secondViewController.delegateFirstViewController = self
}
// MARK: - protocol methods
func dataCaptured(with value: SampleData) {
// we captured data from secondViewController
print("data : \(value.temp)")
}
}
class SecondViewController: UIViewController {
weak var delegateFirstViewController: DataPassProtocol?
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.asyncAfter(deadline: .now() 3) {
self.sendSomeDataToFirstViewController()
}
}
func sendSomeDataToFirstViewController() {
delegateFirstViewController?.dataCaptured(with: SampleData(temp: "Tadaaaaaaa"))
}
}
struct SampleData {
let temp: String
}
protocol DataPassProtocol: AnyObject {
func dataCaptured(with value: SampleData)
}