OmO Walker
OmO Walker

Reputation: 646

Changing Label text on main controller after modal closed swift macOS

I am using delegates to get a string value from my modal. When the modal closes I am trying to update Label text using that string. However, I am getting error: Unexpectedly found nil while implicitly unwrapping an Optional value: file. I am not sure how to fix this. I think it's happening because the view is not yet active.

import Cocoa

class ViewControllerA: NSViewController, SomeDelegate {
    @IBOutlet weak var msgLabel: NSTextField!

    var s: String = "";

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    func setDetails(s: String) {
        self.user = s;
        print("Notified", self.s) // <-- prints: Notified hello again
        msgLabel.stringValue = self.s <-- DOESN'T WORK
    }


    func showModal() -> Void {

        msgLabel.stringValue = "hello" // <--- WORKS
        let cbvc: NSViewController = {
            return self.storyboard!.instantiateController(withIdentifier: "ControllerBVC")
            as! NSViewController
        }()

        self.presentAsModalWindow(cbvc);
    }

    @IBAction func onBtn(_ sender: Any) {
        self.showModal();
    }
}

protocol SomeDelegate {
    func setDetails(s: String)
}


class ViewControllerB: NSViewController {

    @IBOutlet weak var textF: NSTextField!

    var delegate: SomeDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        let vc = ViewControllerA()
        self.delegate = vc
    }

    @IBAction func onBtn(_ sender: Any) {
        DispatchQueue.main.async {
                        self.delegate?.setDetails(s: self.textF.stringValue)
                        self.dismiss("ControllerAVC")
                    }
    }
}

Upvotes: 0

Views: 220

Answers (1)

Rob C
Rob C

Reputation: 5073

You have a number of problems.

In ViewControllerB.viewDidLoad you are assigning a new instance of ViewControllerA to the delegate property. Don't do that. Your viewDidLoad method should look like this:

override func viewDidLoad() {
    super.viewDidLoad()
}

In the showModal method ViewControllerA should assign itself as the delegate on ViewControllerB before ViewControllerB it is presented.

func showModal() -> Void {
    let cbvc: NSViewController = {
        let vc = self.storyboard!.instantiateController(withIdentifier: "ControllerBVC")
        as! ViewControllerB
        vc.delegate = self
        return vc
    }()

    self.presentAsModalWindow(cbvc);
}

In the setDetails method just assign the string to your text field directly:

func setDetails(s: String) {
    msgLabel.stringValue = s
}

Upvotes: 2

Related Questions