如何让NSViewController与Swift中的NSToolbar通信?

时间:2015-05-25 14:05:45

标签: xcode macos swift interface-builder

我在Interface Builder中创建了一个简单的OS X应用程序:

背景故事

MainViewNSViewController的子类,工具栏是我使用Interface Builder构建的简单NSToolbar。默认情况下,NSToolbar项已启用,但在Main Image View包含NSImage之前它们没有任何用途,因此我希望我的NSViewControllerMainView)启用工具栏按钮它接收图像,并在"清除"按下按钮。

问题

为了实现工具栏操作,我按了this answer,现在我有一个MainView.swift实现NSViewController,其中包含工具栏IBActions(并且它可以正常工作),所以我的工具栏可以将动作发送到我的视图。但我无法让工具栏接收来自NSViewController的消息,因为它们不在同一个对象中:我的工具栏位于Window,我的MainImageView位于{{1}查看。

问题

从我的搜索结果来看,我应该使用一个委托,所以我开始制作一个简单的协议:

MainView

但是,在protocol MainToolbarDelegate { func setButtonsEnabled(to:Bool) } 中设置var delegate: MainToolbarDelegate时,我遇到了同样的问题:我无法指向工具栏,因为它不在同一个对象中,并且没有segue链接到另一个。我试过class MainView: NSViewController,但Xcode给我一个错误。

所以现在,我的问题是:我错过了什么?这是我第一次使用代表,所以我可能会做一些完全错误的事情。我是否需要继承我的Window以便我可以使用segues?

如果我的问题不准确,我再次抱歉,我完全迷失了。

1 个答案:

答案 0 :(得分:2)

使用通知!

假设您要根据ViewControler中执行的操作启用/禁用删除项目按钮。首先,您需要添加一些自定义通知(这适用于Xcode 8 beta 6上的Swift 3,语法和命名可能因您的版本或最终版本而异):

extension Notification.Name {
    static let rowSelected = Notification.Name("turnOn")
    static let rowDeselected = Notification.Name("turnOff")
}

接下来,您需要为要使用的按钮添加插座,以及窗口控制器中的观察器和功能来处理操作:

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
    }
}

然后你需要一个View控制器来发送动作。在这种情况下,视图中会有两个按钮:

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))
    }
}