如何在 Xcode 6 和 Storyboard 中使用 NSToolBar?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24219441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 05:05:13  来源:igfitidea点击:

How to use NSToolBar in Xcode 6 and Storyboard?

xcodecocoaswiftstoryboardnstoolbar

提问by Blaszard

I've been trying to build on a Cocoa app that uses Swift and Storyboard in Xcode 6, but how can I use NSToolbarthere?

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

In Xcode 5 and xib, you can add NSToolbarfrom within Object Library to any .xib files and then click on the added toolbar to expand it and drag and drop a connection from any items there to a AppDelegate.hfile. In this way you can create a IBActionor IBOutletconnection. I confirmed that this can also be done if you use Swift and non-storyboard in Xcode 6. However, it looks like this is not the case in Xcode 6 and Storyboard environment.

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

I first created a project that uses Storyboard in Xcode 6, but then, I wasn't able to add a NSToolbarfrom within Object Library to a View Controller in Storyboard. So I added it to Window Controller's Window object in Storyboard. However, in this way I cannot create those connections from any items in the expanded toolbar to either AppDelegate.swiftor ViewController.swift.

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

So my question is:

所以我的问题是:

  • Is it feasible to create a storyboard app that uses NSToolbar?
  • If it is feasible, is the addition of NSToolbarto the Window Controller the proper way to use NSToolBarin Storyboard?
  • Finally, how can I create @IBOutletand @IBActionconnections there?
  • 创建一个使用 的故事板应用程序是否可行NSToolbar
  • 如果可行,添加NSToolbar到 Window Controller 是NSToolBar在 Storyboard 中使用的正确方法吗?
  • 最后,我如何在那里创建@IBOutlet@IBAction连接?

UPDATE

更新

I found that the accepted answer by @GeorgeVillasboas only works for @IBAction. I am still looking for how to create an @IBOutletconnection...

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

回答by George Villasboas

I had this very same problem. The solution works for both Objective-C and Swift projects.

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

Working with Storyboards on OSX, it creates an instance of NSWindow and segues to another NSViewController as its Window Content Segue, as you described.

在 OSX 上使用 Storyboards,它创建了一个 NSWindow 实例,并按照您的描述将另一个 NSViewController 作为其窗口内容 Segue。

On your ViewController, create a standard IBAction to receive the action when the toolbar is clicked. To wire it up with the NSToolbar, just control-drag (or leftClick-drag) from your NSToolbarItem to the FirstResponder object, as shown on the picture below.

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

Wiring up a NSToolbar on XCode 6

在 XCode 6 上连接 NSToolbar

This will open a HUGElist of available connections. Your IBAction will be on that list. Just selected it and you're good to go.

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

Hope this helps!

希望这可以帮助!

回答by Grimxn

Here's an answer that doesn't rely on run-time hook-ups - @cdalvaro's answer gets most of the way there for some applications, but isn't full, and it requires the ViewController to know about the artificial NSWindowController, which doesn't feel right.

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

Like @cdalvaro, the first step is to build your own subclass of NSWindowController, and to set the Storyboard WC to that class. You can then create all of your connections to and from the NSToolbar(both @IBOutlets & @IBActions) in the new WindowController. So far so good.

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

The last step, which I haven't seen anywhere else, is how to refer to the ViewController in the WindowController - you can't create an @IBOutletto it - for the same reasons that we got here in the first place - you can't create references across scenes in the Storyboard. However, the WindowController must have a reference to the ViewController, and it does... self.window!.contentViewController! as! ViewController

最后一步,我在其他任何地方都没有看到,是如何在 WindowController 中引用 ViewController - 你不能@IBOutlet为它创建一个- 与我们首先来到这里的原因相同 - 你不能在故事板中跨场景创建引用。然而,WindowController 必须有一个对 ViewController 的引用,而且它确实......self.window!.contentViewController! as! ViewController

Here's a complete WindowController with a checkbox that sets values in the ViewController, without the ViewController having to know anything...

这是一个完整的 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
    }
}

回答by Carlos D. álvaro

This helped me for the IBOutlet solution you are looking for: https://stackoverflow.com/a/27555237/3398062

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

Update (explanation)

更新(说明)

I discovered this thread because I was trying to create a Circular Progress Indicator inside the toolbar and I didn't know how to animate it from the ViewController since the IBOutlet was declared inside a custom WindowController.

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

Finally, I found the post that I have added above which describes how to access to IBOutlets from other classes.

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

In essence what I have done is the following:

实质上,我所做的是以下内容:

  • Create a custom NSWindowController subclass (CustomWindowController) for the Window Controller so I can add the IBOutlet for the ProgressIndicator:
  • 为窗口控制器创建一个自定义 NSWindowController 子类 (CustomWindowController),以便我可以为 ProgressIndicator 添加 IBOutlet:

Code Example:

代码示例:

@interface CustomWindowController : NSWindowController

@property (weak) IBOutlet NSProgressIndicator *progressIndicator;

@end
  • Then in the ViewController class, in the method I want to use to update the state of the Progress Indicator, I create and object of the custom Window Controller.
  • 然后在 ViewController 类中,在我想用来更新进度指示器状态的方法中,我创建了自定义窗口控制器的对象。

Code Example:

代码示例:

CustomWindowController *customWindowController = self.view.window.windowController;`
  • Finally, to change the state of the Progress Indicator there is only to call the method from the created custom object.
  • 最后,要更改进度指示器的状态,只需从创建的自定义对象调用该方法。

Code Example:

代码示例:

[customWindowController.progressIndicator startAnimation:sender];

or

或者

[customWindowController.progressIndicator stopAnimation:sender];

回答by balazs630

This video helped me how to create a toolbar without writing a single line of code: https://www.youtube.com/watch?v=XSQocHG3IjA

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

You can add the 'Window Controller' item from the Object Library (if you don't have one), connect to a View Controller (where you want your toolbar to display) and follow the video! For custom Toolbar buttons add 'Image Button' item to the Toolbar just by dragging from the Object Library. Then you can pick an image for a button, set the size and so on...

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

回答by nsij22

Here is a general solution for the outlets and actions. it allows you to preform all the the same functions as an iboutlet would for a tool bar item and also allows you to set the button to a function instead of creating an ibaction. hope it helps :P

这是插座和动作的通用解决方案。它允许您为工具栏项目执行与 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
}
}

Here is a link to my question attempting to get a cleaner answer http://www.stackoverflow.com/questions/27371439/use-nstoolbar-outlet-xcode-6-and-storyboard/27374449but it looks like from the answers i have gotten so far this is the best option.

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

回答by Mark Lilback

The same problem of IBOutlets also applies to KVO. One of the features of the NSSplitViewController is the canCollapse property for each split view item which supports KVO, but this is unusable in IB just like IBOutlets.

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

The only workaround I can see is to add a NSObjectController to each scene and when the scene loads, set the object controller's object to the object in the other scene (already loaded) that you want to reference.

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