这里简化了我的问题。我有一个工具栏,窗口中有一个按钮, View 中有一个标签。单击按钮时,我想让 label.stringValue 从“ON”变为“OFF”
这是窗口 Controller :
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()
}
}
这是 View Controller :
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"
}
}
当我点击按钮时出现这个错误:
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"
}
}
}
最佳答案
我希望这个答案还不算太晚。
委托(delegate)的工作方式是您告诉发件人要发送给谁。您遇到的问题是您创建了一个新的 WindowController
实例并将其注册为接收者。问题是 WindowController
的新实例不是发送按钮点击操作的实例。
要使其正常工作,您必须将 ViewController
注册到 WindowController
的唯一实例。
而不是做
let vc = WindowController()
vc.viewDelegate = self
您需要找到实际的 Window Controller 实例并注册到该实例。将上面的代码改成:
(self.view.window?.windowController as! WindowController).delegate = self
一切都应该完美无缺。
关于swift - OSX : Delegating between a NSWindowController and a NSViewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52215402/