osx:在NSWindowController和NSViewController之间委托

时间:2018-09-07 04:40:18

标签: swift macos appdelegate swift-protocols

这是我的问题简化了。我有一个工具栏,在“窗口”中有一个按钮,在“视图”中有一个标签。单击按钮后,我想将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 :(得分:1)

我希望这个答案不会太晚。

委托的工作方式是您告诉发件人发送给谁。您遇到的问题是您创建了一个新的WindowController实例并注册为它的接收者。问题在于WindowController的新实例不是发送按钮单击操作的实例。

要使其生效,您必须将ViewController注册到WindowController的唯一实例。

代替做

let vc = WindowController()
vc.viewDelegate = self

您需要找到实际的Window Controller实例并进行注册。将上面的代码更改为:

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

一切都应该正常工作。