Home > OS >  Cocoa Swift - Pass data from two ViewControllers
Cocoa Swift - Pass data from two ViewControllers

Time:10-12

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)
}
  • Related