osx: 在 NSWindowController 和 NSViewController 之间进行委托
osx: Delegating between a NSWindowController and a NSViewController
这里简化了我的问题。我有一个工具栏,在 Window 中有一个按钮,在视图中有一个标签。单击按钮后,我想 label.stringValue 从 "ON" 变为 "OFF"
这是 Window控制器:
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"
}
}
}
这是故事板:
当我点击按钮时出现这个错误:
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"
}
}
}
希望这个回答还不算太晚。
委托的工作方式是您告诉发件人要发送给谁。您遇到的问题是您创建了一个新的 WindowController
实例并注册为它的接收者。问题是 WindowController
的新实例不是发送按钮点击操作的实例。
要使其正常工作,您必须将 ViewController
注册到 WindowController
的唯一实例。
而不是做
let vc = WindowController()
vc.viewDelegate = self
您需要找到实际的 Window 控制器实例并注册到该实例。将上面的代码改成:
(self.view.window?.windowController as! WindowController).delegate = self
一切都应该完美无缺。
这里简化了我的问题。我有一个工具栏,在 Window 中有一个按钮,在视图中有一个标签。单击按钮后,我想 label.stringValue 从 "ON" 变为 "OFF"
这是 Window控制器:
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"
}
}
}
这是故事板:
当我点击按钮时出现这个错误:
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"
}
}
}
希望这个回答还不算太晚。
委托的工作方式是您告诉发件人要发送给谁。您遇到的问题是您创建了一个新的 WindowController
实例并注册为它的接收者。问题是 WindowController
的新实例不是发送按钮点击操作的实例。
要使其正常工作,您必须将 ViewController
注册到 WindowController
的唯一实例。
而不是做
let vc = WindowController()
vc.viewDelegate = self
您需要找到实际的 Window 控制器实例并注册到该实例。将上面的代码改成:
(self.view.window?.windowController as! WindowController).delegate = self
一切都应该完美无缺。