【问题标题】:How can I make an NSViewController communicate with an NSToolbar in Swift?如何让 NSViewController 与 Swift 中的 NSToolbar 通信?
【发布时间】:2015-08-07 01:04:18
【问题描述】:

我正在制作一个简单的 OS X 应用程序,看起来像在 Interface Builder 中:

背景故事

MainViewNSViewController 的子类,工具栏是我使用Interface Builder 构建的简单NSToolbar。默认情况下,NSToolbar 项目是启用的,但直到Main Image View 包含NSImage 之前它们没有任何用途,所以我希望我的NSViewController (MainView) 在收到图像时启用工具栏按钮,并禁用它们当按下“清除”按钮时。

问题

为了实现工具栏操作,我遵循this answer,所以现在我有一个MainView.swift 实现NSViewController,其中包含工具栏IBActions(并且有效),所以我的工具栏可以将操作发送到我的视图。但是我无法让工具栏接收来自NSViewController 的消息,因为它们不在同一个对象中:我的工具栏在Window 中,我的MainImageViewMainView 的视图中。

问题

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

protocol MainToolbarDelegate {
     func setButtonsEnabled(to:Bool)
} 

但是,在我的class MainView: NSViewController 中设置var delegate: MainToolbarDelegate 时,我遇到了同样的问题:我无法指向工具栏,因为它不在同一个对象中,并且没有将一个对象链接到另一个对象的segue。我尝试了var delegate: MainToolbarDelegate = self.view.window.toolbar,但 Xcode 返回了一个错误。

所以现在,我的问题是:我错过了什么?那是我第一次使用委托,所以我可能会做一些完全错误的事情。我是否需要子类化我的 Window 以便我可以使用 segues?

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

【问题讨论】:

  • 我认为子类化 NSWindowController 会容易得多。这是我的答案之一,与您的情况类似...stackoverflow.com/questions/28916862/…
  • 我在您发表评论前几分钟就发现了这一点,它似乎有效,谢谢!

标签: xcode macos swift interface-builder


【解决方案1】:

使用通知!

假设您想根据在 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
    }
}

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-26
  • 1970-01-01
  • 2021-03-06
  • 2011-03-26
  • 1970-01-01
相关资源
最近更新 更多