如何让 NSViewController 与 Swift 中的 NSToolbar 通信?
How can I make an NSViewController communicate with an NSToolbar in Swift?
我正在制作一个简单的 OS X 应用程序,在 Interface Builder 中看起来像这样:
背景故事
MainView
是 NSViewController
的子类,工具栏是我用 Interface Builder 构建的简单 NSToolbar
。默认情况下,NSToolbar 项是启用的,但它们在 Main Image View
包含 NSImage
之前没有任何用处,所以我希望我的 NSViewController
(MainView
) 在以下情况下启用工具栏按钮它接收图像,并在按下 "Clear" 按钮时禁用它们。
问题
为了实现工具栏操作,我遵循了 this answer,所以现在我有一个 MainView.swift
实现了 NSViewController
,其中包含工具栏 IBActions(并且有效),所以我的工具栏可以将操作发送到我的视图。但是我没有办法让工具栏接收来自NSViewController
的消息,因为它们不在同一个对象中:我的工具栏在Window
,我的MainImageView
在[=12] =]的观点。
问题
根据我的搜索结果,我应该使用委托,所以我开始制作一个简单的协议:
protocol MainToolbarDelegate {
func setButtonsEnabled(to:Bool)
}
但是,当在我的 class MainView: NSViewController
中设置 var delegate: MainToolbarDelegate
时,我遇到了同样的问题:我无法指向工具栏,因为它不在同一个对象中,并且没有 segue 链接一个到另一个。我试过 var delegate: MainToolbarDelegate = self.view.window.toolbar
但 Xcode returns 我出错了。
所以现在,我的问题是:我错过了什么?那是我第一次使用委托,所以我可能会做一些完全错误的事情。我是否需要子类化我的 Window 以便我可以使用 segues?
如果我的问题不准确,再次抱歉,我完全迷路了。
使用通知!
假设您想要 enable/disable 根据在 ViewControler 中执行的操作移除项目按钮。首先,您需要添加一些自定义通知(这是针对 Xcode 8 beta 6 上的 Swift 3,语法和命名可能因您的版本或最终版本而异):
extension Notification.Name {
static let rowSelected = Notification.Name("turnOn")
static let rowDeselected = Notification.Name("turnOff")
}
接下来,您需要为要使用的按钮添加一个出口,以及 window 控制器中的观察者和函数来处理操作:
class SummaryWindowController: NSWindowController {
@IBOutlet weak var removeProjectButton: NSToolbarItem!
required init?(coder: NSCoder) {
super.init(coder: coder)
shouldCascadeWindows = true
}
override init(window: NSWindow?) {
super.init(window: window)
}
override func windowDidLoad() {
super.windowDidLoad()
self.removeProjectButton.isEnabled = false
NotificationCenter.default.addObserver(self, selector: #selector(SummaryWindowController.enableRemoveButton(_:)), name: .turnOn, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(SummaryWindowController.disableRemoveButton(_:)), name: .turnOff, object: nil)
}
func enableRemoveButton(_ notification: Notification) {
self.removeProjectButton.isEnabled = true
}
func disableRemoveButton(_ notification: Notification) {
self.removeProjectButton.isEnabled = false
}
}
然后您需要一个视图控制器来发送操作。在这种情况下,它将是视图中的两个按钮:
class SummaryViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func onButtonTapped(sender: NSButton) {
NotificationCenter.default.post(Notification(name: .turnOn))
}
@IBAction func offButtonTapped(sender: NSButton) {
NotificationCenter.default.post(Notification(name: .turnOff))
}
}
我正在制作一个简单的 OS X 应用程序,在 Interface Builder 中看起来像这样:
背景故事
MainView
是 NSViewController
的子类,工具栏是我用 Interface Builder 构建的简单 NSToolbar
。默认情况下,NSToolbar 项是启用的,但它们在 Main Image View
包含 NSImage
之前没有任何用处,所以我希望我的 NSViewController
(MainView
) 在以下情况下启用工具栏按钮它接收图像,并在按下 "Clear" 按钮时禁用它们。
问题
为了实现工具栏操作,我遵循了 this answer,所以现在我有一个 MainView.swift
实现了 NSViewController
,其中包含工具栏 IBActions(并且有效),所以我的工具栏可以将操作发送到我的视图。但是我没有办法让工具栏接收来自NSViewController
的消息,因为它们不在同一个对象中:我的工具栏在Window
,我的MainImageView
在[=12] =]的观点。
问题
根据我的搜索结果,我应该使用委托,所以我开始制作一个简单的协议:
protocol MainToolbarDelegate {
func setButtonsEnabled(to:Bool)
}
但是,当在我的 class MainView: NSViewController
中设置 var delegate: MainToolbarDelegate
时,我遇到了同样的问题:我无法指向工具栏,因为它不在同一个对象中,并且没有 segue 链接一个到另一个。我试过 var delegate: MainToolbarDelegate = self.view.window.toolbar
但 Xcode returns 我出错了。
所以现在,我的问题是:我错过了什么?那是我第一次使用委托,所以我可能会做一些完全错误的事情。我是否需要子类化我的 Window 以便我可以使用 segues?
如果我的问题不准确,再次抱歉,我完全迷路了。
使用通知!
假设您想要 enable/disable 根据在 ViewControler 中执行的操作移除项目按钮。首先,您需要添加一些自定义通知(这是针对 Xcode 8 beta 6 上的 Swift 3,语法和命名可能因您的版本或最终版本而异):
extension Notification.Name {
static let rowSelected = Notification.Name("turnOn")
static let rowDeselected = Notification.Name("turnOff")
}
接下来,您需要为要使用的按钮添加一个出口,以及 window 控制器中的观察者和函数来处理操作:
class SummaryWindowController: NSWindowController {
@IBOutlet weak var removeProjectButton: NSToolbarItem!
required init?(coder: NSCoder) {
super.init(coder: coder)
shouldCascadeWindows = true
}
override init(window: NSWindow?) {
super.init(window: window)
}
override func windowDidLoad() {
super.windowDidLoad()
self.removeProjectButton.isEnabled = false
NotificationCenter.default.addObserver(self, selector: #selector(SummaryWindowController.enableRemoveButton(_:)), name: .turnOn, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(SummaryWindowController.disableRemoveButton(_:)), name: .turnOff, object: nil)
}
func enableRemoveButton(_ notification: Notification) {
self.removeProjectButton.isEnabled = true
}
func disableRemoveButton(_ notification: Notification) {
self.removeProjectButton.isEnabled = false
}
}
然后您需要一个视图控制器来发送操作。在这种情况下,它将是视图中的两个按钮:
class SummaryViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func onButtonTapped(sender: NSButton) {
NotificationCenter.default.post(Notification(name: .turnOn))
}
@IBAction func offButtonTapped(sender: NSButton) {
NotificationCenter.default.post(Notification(name: .turnOff))
}
}