osx: делегирование между NSWindowController и NSViewController - PullRequest
0 голосов
/ 07 сентября 2018

Вот моя упрощенная проблема. У меня есть панель инструментов с кнопкой в ​​окне и метка в представлении. Когда кнопка нажата, я хочу, чтобы label.stringValue перешел из «ON» в «OFF»

Вот WindowController:

protocol ViewControllerDelegate {
    func switchOnOff()
}

class WindowController: NSWindowController {
    var viewDelegate: ViewControllerDelegate?
    @IBAction func pressedButton(_ sender: Any) {
        var vc = storyboard?.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "ViewController")) as? ViewController
        vc?.switchOnOff()
    }    
    override func windowDidLoad() {
        super.windowDidLoad()
    }
}

А вот контроллер вида:

class ViewController: NSViewController {
    @IBOutlet weak var onOffLabel: NSTextField!
    override func viewDidLoad() {
        super.viewDidLoad()
        let vc = WindowController()
        vc.viewDelegate = self    }

    override var representedObject: Any? {
        didSet {
        }
    }
}

extension ViewController: ViewControllerDelegate {
func switchOnOff() {
    if (onOffLabel.stringValue == "OFF" ) {
        onOffLabel.stringValue = "ON"
    } else {
        onOffLabel.stringValue = "OFF"
    }       
}

}

Это раскадровка: enter image description here

Когда я нажимаю кнопку, я получаю эту ошибку:

extension ViewController: ViewControllerDelegate {
    func switchOnOff() {
        if (onOffLabel.stringValue == "OFF" ) { // Thread 1: Fatal error: Unexpectedly found nil while unwrapping 
        an Optional value
            onOffLabel.stringValue = "ON"
        } else {
            onOffLabel.stringValue = "OFF"
        }
    }
}

1 Ответ

0 голосов
/ 11 марта 2019

Надеюсь, этот ответ еще не поздно.

Работа делегата заключается в том, что вы сообщаете отправителю, кому отправлять сообщения. Проблема в том, что вы создали новый экземпляр WindowController и зарегистрировались в качестве его получателя. Проблема в том, что новый экземпляр WindowController НЕ тот, который отправляет действия нажатия кнопки.

Чтобы это работало, вы должны зарегистрировать свой ViewController в единственном экземпляре WindowController.

Вместо того, чтобы делать

let vc = WindowController()
vc.viewDelegate = self

Вам нужно найти фактический экземпляр Window Controller и зарегистрироваться на него. Измените приведенный выше код на:

(self.view.window?.windowController as! WindowController).delegate = self

И все должно работать без нареканий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...