osx:在 NSWindowController 和 NSViewController 之间进行委托
Posted
技术标签:
【中文标题】osx:在 NSWindowController 和 NSViewController 之间进行委托【英文标题】:osx: Delegating between a NSWindowController and a NSViewController 【发布时间】:2018-09-07 04:40:18 【问题描述】:这是我的问题简化。我有一个工具栏,窗口中有一个按钮,视图中有一个标签。单击按钮时,我想将 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"
这是故事板:
当我单击按钮时出现此错误:
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"
【问题讨论】:
关于:var vc = storyboard?.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "ViewController")) as? ViewController
... 相关场景是否确实名为“ViewController”?
故事板 ID = ViewController 和属性检查器中的标题 == ViewController。在哪里可以找到场景的名称?
@Mitch Kroska – 听起来不错(我并没有真正使用 Storyboard,所以没有更多可添加的内容,抱歉!)。
【参考方案1】:
希望这个答案还不算晚。
委托的工作方式是告诉发件人要发送给谁。您遇到的问题是您创建了一个新的 WindowController
实例并注册为它的接收者。问题是WindowController
的新实例不是发送按钮单击操作的实例。
要使其工作,您必须将您的ViewController
注册到WindowController
的唯一实例。
而不是做
let vc = WindowController()
vc.viewDelegate = self
您需要找到实际的 Window Controller 实例并注册到该实例。把上面的代码改成:
(self.view.window?.windowController as! WindowController).delegate = self
一切都应该完美无缺。
【讨论】:
以上是关于osx:在 NSWindowController 和 NSViewController 之间进行委托的主要内容,如果未能解决你的问题,请参考以下文章
如何通过按 ESC 键关闭窗口(NSWindowController)?
来自 NSWindowController Cocoa 的自定义视图
NSManagedObjectContext 传递给 NSWindowController 变为 nil
Interface builder中的NSWindowController对象链接