14

我一直在尝试构建一个在 Xcode 6 中使用 Swift 和 Storyboard 的 Cocoa 应用程序,但是我该如何使用NSToolbar呢?

在 Xcode 5 和 xib 中,您可以NSToolbar从对象库中添加到任何 .xib 文件,然后单击添加的工具栏以将其展开并将连接从那里的任何项目拖放到AppDelegate.h文件。通过这种方式,您可以创建一个IBActionIBOutlet连接。我确认如果您在 Xcode 6 中使用 Swift 和非故事板,也可以做到这一点。但是,在 Xcode 6 和 Storyboard 环境中似乎并非如此。

我首先在 Xcode 6 中创建了一个使用 Storyboard 的项目,但是后来,我无法将NSToolbar对象库中的一个 from 添加到 Storyboard 中的视图控制器中。所以我将它添加到 Storyboard 中的 Window Controller 的 Window 对象中。但是,通过这种方式,我无法创建从扩展工具栏中的任何项目到AppDelegate.swift或的连接ViewController.swift

所以我的问题是:

  • 创建一个故事板应用程序是否可行NSToolbar
  • 如果可行,添加到 Window Controller 是在 StoryboardNSToolbar中使用的正确方法吗?NSToolBar
  • 最后,我如何在那里创建@IBOutlet@IBAction连接?

更新

我发现@GeorgeVillasboas 接受的答案仅适用于@IBAction. 我仍在寻找如何创建@IBOutlet连接...

4

6 回答 6

27

我遇到了同样的问题。该解决方案适用于 Objective-C 和 Swift 项目。

如您所描述的,在 OSX 上使用 Storyboards 时,它会创建一个 NSWindow 实例并作为它的 Window Content Segue 连接到另一个 NSViewController。

在您的 ViewController 上,创建一个标准 IBAction 以在单击工具栏时接收操作。要将它与 NSToolbar 连接起来,只需从 NSToolbarItem 控制拖动(或左键拖动)到 FirstResponder 对象,如下图所示。

在 XCode 6 上连接一个 NSToolbar

这将打开一个巨大的可用连接列表。您的 IBAction 将在该列表中。刚刚选择它,你很高兴。

希望这可以帮助!

于 2014-07-17T18:04:44.960 回答
11

这是一个不依赖于运行时连接的答案-@cdalvaro 的答案在某些应用程序中得到了大部分的解决方案,但并不完整,它需要 ViewController 了解人工NSWindowController,这并不感觉对。

与@cdalvaro 一样,第一步是构建您自己的 子类NSWindowController,并将 Storyboard WC 设置为该类。然后,您可以在新的 WindowController 中创建与NSToolbar@IBOutlets & s)之间的所有连接。@IBAction到现在为止还挺好。

最后一步,我在其他任何地方都没有看到,是如何在 WindowController 中引用 ViewController - 你不能创建一个@IBOutletto 它 - 出于同样的原因,我们首先来到这里 - 你不能在情节提要中创建跨场景的引用。但是,WindowController 必须具有对 ViewController 的引用,并且它确实...self.window!.contentViewController! as! ViewController

这是一个完整的 WindowController,带有一个在 ViewController 中设置值的复选框,而 ViewController 不必知道任何事情......

class MyWindowController: NSWindowController {

    var viewController: ViewController {
        get {
            return self.window!.contentViewController! as! ViewController
        }
    }

    @IBOutlet weak var aSwitch: NSButton!
    @IBAction func toolbarActionA(sender: AnyObject) {
        println("toolbarActionA")
        self.viewController.a = !self.viewController.a
        self.aSwitch.state = self.viewController.a ? NSOnState : NSOffState
    }
}
于 2015-04-09T18:35:39.250 回答
4

这有助于我找到您正在寻找的 IBOutlet 解决方案: https ://stackoverflow.com/a/27555237/3398062

更新(解释)

我发现这个线程是因为我试图在工具栏中创建一个循环进度指示器,但我不知道如何从 ViewController 对其进行动画处理,因为 IBOutlet 是在自定义 WindowController 中声明的。

最后,我找到了我在上面添加的帖子,它描述了如何从其他类访问 IBOutlets。

本质上,我所做的如下:

  • 为 Window Controller 创建一个自定义 NSWindowController 子类 (CustomWindowController),这样我就可以为 ProgressIndicator 添加 IBOutlet:

代码示例:

@interface CustomWindowController : NSWindowController

@property (weak) IBOutlet NSProgressIndicator *progressIndicator;

@end
  • 然后在 ViewController 类中,在我想用来更新进度指示器状态的方法中,创建自定义窗口控制器的对象。

代码示例:

CustomWindowController *customWindowController = self.view.window.windowController;`
  • 最后,要更改进度指示器的状态,只需从创建的自定义对象调用方法。

代码示例:

[customWindowController.progressIndicator startAnimation:sender];

或者

[customWindowController.progressIndicator stopAnimation:sender];
于 2015-04-05T09:45:39.513 回答
2

该视频帮助我如何在不编写任何代码的情况下创建工具栏:https ://www.youtube.com/watch?v=XSQocHG3IjA

您可以从对象库中添加“窗口控制器”项目(如果您没有),连接到视图控制器(您希望工具栏显示的位置)并观看视频!对于自定义工具栏按钮,只需从对象库中拖动即可将“图像按钮”项目添加到工具栏。然后你可以选择一个按钮的图像,设置大小等等......

于 2017-02-21T16:49:13.907 回答
0

这是插座和操作的一般解决方案。它允许您执行与 iboutlet 用于工具栏项的所有相同功能,还允许您将按钮设置为功能而不是创建 ibaction。希望它有所帮助:P

override func viewDidLayout() {
var x = self.view.window?.toolbar?.items[1].label
println(x)
if(self.view.window?.toolbar?.items[0].label! != "Check")
{
    toobarediting()
}
println("didlay")
}

func toobarediting() {
self.view.window?.toolbar?.insertItemWithItemIdentifier("Check", atIndex: 0)
}

func toolbarcheck(functiontoset: Selector) {
var y = self.view.window?.toolbar?.items[0] as NSToolbarItem
y.action = functiontoset
if(functiontoset != nil)
{
    y.enabled = true
}
}

这是我的问题的链接,试图获得更清晰的答案 http://www.stackoverflow.com/questions/27371439/use-nstoolbar-outlet-xcode-6-and-storyboard/27374449 但看起来像我的答案到目前为止,这是最好的选择。

于 2014-12-09T08:39:23.973 回答
-1

IBOutlets 的同样问题也适用于 KVO。NSSplitViewController 的特性之一是支持 KVO 的每个拆分视图项的 canCollapse 属性,但这在 IB 中无法使用,就像 IBOutlets 一样。

我能看到的唯一解决方法是为每个场景添加一个 NSObjectController,当场景加载时,将对象控制器的对象设置为您想要引用的另一个场景(已经加载)中的对象。

于 2015-02-20T07:54:55.030 回答