嗨,我已经看到这个问题被问过几次了,但还没有明确的答案,所以我为 xcode 7 和 swift2 创建了它(无论如何,这可能已经改变了一些事情)。
我使用 Xcode 7 和 Cocoa OSX Storyboard + swift2 创建了一个项目,因此我的项目从连接到 NSViewController 的 NSWindowController 开始(正如预期的那样!)。我向窗口控制器添加了一个 NSToolbar ,并向工具栏添加了一个 NSButton 。我将 NSViewController 更改为新的 NSSplitViewController 之一,它链接到三个 NSViewController 并水平显示它们的视图 - 带有垂直分隔线 - (类似于您在照片应用程序或优胜美地 + 中的页面)。我的最终目标是我的工具栏中的按钮显示和隐藏第一个分割。
我的理解是,我希望为了实现这一目标,我应该在 NSSplitViewController 中创建一个操作,该操作或多或少地改变自动布局约束,它们在这里的工作方式如下: 如何在 Mac 应用程序中折叠和展开视图?。
然后以某种方式将此操作链接到工具栏中的 NSButton...它恰好位于 NSWindowController 中(在层次结构中很远且隔离)...
我已经解决了有关 NSToolbar 和故事板的其他问题,但未能解决实现我的目标:
- 我在该问题中看到的最新评论似乎是解决问题的最佳方法(但仍然不如我想象的那么好)是将 NSObjectController 添加到每个场景的停靠栏,并且当场景加载后,将对象的值设置为其他场景的控制器。这真的是最好的前进方式吗?如果是这样,我怎样才能实现这一目标?
Apple 在 WWDC15 中确实提到(再次)他们为 osx 和拥有视图控制器的分割视图控制器创建了故事板,以便您可以将逻辑和工作移动到特定的视图控制器,所以我希望从在我的分割视图控制器中,因为这是需要更改的目标。
有谁知道如何从视图控制器本身实现这一点?我确实无法找到将 ToolBarItem 连接到它的方法。
Hi I've seen this question asked a few times already but with no definite answer yet so I created it for xcode 7 and swift2 (which may have changed things a bit anyway).
I created a project using Xcode 7 and Cocoa OSX Story boards + swift2, so my project started with a NSWindowController that Connects to a NSViewController (as expected!). I added a NSToolbar to my window controller and added a NSButton to the toolbar. I changed my NSViewController to be one of the new NSSplitViewController that links to three NSViewControllers and displays their views horizontally - with vertical dividers - (similar to the layout you see in the photo app or pages in Yosemite +). My final goal will be that the button in My toolbar shows and hides the first split.
It is my understanding is, and I would expect that to achieve this I should create an action in the NSSplitViewController that changes the auto layout constrains more or less in the way they are working it out here: How to do collapse and expand view in mac application?.
And then somehow link this action to the NSButton that is in the Toolbar... which happens to be in the NSWindowController (far up and isolated in the hierarchy)...
I have already gone through other questions about NSToolbar and storyboards and failed to accomplish my goal:
- The YouTube video: Cocoa Programming L17 - NSToolbar which is the closest I found to solve the problem, but his method does not work for storyboards, only creating your own xib file.
- In this question: How to use NSToolBar in Xcode 6 and Storyboard? One person proposes to make the link using the first reponder and expecting everything to hook up at run-time (which looks a bit dodgy and not the way apple would implement it I think...). A second person suggested to create a view controller variable in the NSWindowController and manipulate its properties from there... but again, a bit dodgy too.
- One latest comment I saw in that question which seems the best way to tackle the problem (but still not as good as I guess it could be) is to add a NSObjectController to the dock of each scene and when the scene loads, set the values of the objects to the other secene's controller. Is this really the best way to go ahead? If so, how could I achieve this one?
Apple did mention (again) in WWDC15 that they created storyboards for osx and the split-view controller that owns view-controllers so that you can move your logic and work to the specific view-controller, so I would be expecting to do everything from inside my split-view controller as this is the target that needs to change.
Does anyone know how to achieve this from the view controller itself? I really haven't been able to find a way to connect my ToolBarItem to it.
发布评论
评论(4)
好的,我几天前就创建了这个问题,到目前为止还没有答案,所以我用我最近为克服这个问题所做的事情来回答。
创建 Xcode 项目后,我执行了以下操作:
为每个 NSSplitViewItem 添加一个 IBOutlet。例如:
@IBOutlet weak var mySplitViewItem: NSSplitViewItem!
为 NSWindowController 创建
MySplitViewController
var mySplitViewController: MySplitViewController {
返回 self.window?.contentViewController 作为!我的SplitViewController
添加了
mySplitViewController。 mySplitViewItem.collapsed = true
我创建了一些示例代码来执行此操作(但使用视图控制器并更改标签的文本 here ,以防万一有人想看到具有这种行为的工作项目和 博客文章也有关于它的内容:)
OK, I've created this question quite a few days ago and no answer so far so I've answer with what I recently did to overcome the problem.
After I created my Xcode project I did this:
Added an IBOutlet for each NSSplitViewItem. For example:
@IBOutlet weak var mySplitViewItem: NSSplitViewItem!
Created a subclass WindowController for the NSWindowController
Added a property that gets the Window Controller's content as MySplitViewController
var mySplitViewController: MySplitViewController {
return self.window?.contentViewController as! MySplitViewController
}
Now I can access the split view controller's property from the Window Controller in the action I created:
mySplitViewController. mySplitViewItem.collapsed = true
I created some sample code that does this (but using a view controller and changing the text for a label here, just in case someone wants to see a working project with this behaviour. And a blog post about it too :)
我认为这个第一响应者方法实际上是正确的方法。
举个例子:
添加类似于以下内容的内容,无论在哪个视图控制器中都有意义。
这将神奇地显示在第一个响应者中:
在故事板中,右键单击窗口控制器上方的橙色“第一响应者”图标,您应该会在中看到
doSomething
非常长长的名单。您只需将其连接到工具栏按钮即可。在下面的屏幕截图中,您可以看到我的“切换侧边栏”按钮已连接到第一响应者中的
toggleSidebar
操作。我什至不必编写这个方法 - 它是由
NSSplitViewController
提供的:I think this first responder method is actually the proper way.
As an example:
Add something similar to the following, in whichever view controller makes sense.
This will magically show up in the first responder:
In your storyboard, right-click the orange "first responder" icon above your window controller, and you should see
doSomething
in the very long list. You just need to connect that up to your toolbar button.In the following screen capture, you can see my "Toggle Sidebar" button is connected to the
toggleSidebar
action in my first responder.I didn't even have to write this method — it's provided by
NSSplitViewController
:所以,我正在解决同样的问题,但没有找到像您遇到的解决方案。我阅读了您的帖子,并试图弄清楚当我想到使用通知时如何实施您的解决方案。大约 30 秒后,我有了一个完美的工作解决方案:
在你的 windowController 中添加一个 IBAction 来发布通知,就像这样
将该操作挂接到你的
NSToolbarItem
上,然后在 viewController 中添加 self 作为观察者像这样的通知在您的情况下,选择器将是
updateMyLabelText
我真的没有看到任何缺点。不需要引用其他对象,没有依赖性。对我来说完美无缺
So, I was working this same issue and finding no solution as you experienced. I read your post and was trying to figure how I would implement your solution when it occurred to me to use a notification. In about 30 seconds, I had a perfectly fine working solution:
In your windowController add an IBAction to post a notification like so
Hook up that action to your
NSToolbarItem
, then in the viewController add self as an observer for that notification like soIn your case, selector would be
updateMyLabelText
I don't really see any downside here. No reference to other objects needed, no dependancies. Works flawlessly for me
虽然连接 IBActions 通过使用第一响应者或通过向场景添加“对象”,然后将其类更改为窗口的视图控制器类来工作,但这对您想要指向的 IBOutlet 和委托没有帮助视图控制器。
这是一个解决方法:
将工具栏添加到视图控制器,而不是其窗口。这样,您就可以轻松地在视图控制器场景中建立所有 IBOutlet 连接。我这样做已经很多年了,没有发现任何问题,即使使用选项卡也是如此。
然后,您必须在代码中分配窗口的工具栏。例如这样:
While connectiong IBActions works by using either the First Responder or by adding an "Object" to the scene, then changing its class to the window's view controller class, this doesn't help with IBOutlets and delegates that you'd like to point to the view controller.
Here's a work-around for that:
Add the Toolbar to the View Controller, not to its Window. That way, you can make all the IBOutlet connections in the View Controller Scene easily. I've done that for years and found no issues with it, even when using Tabs.
You'll have to assign the window's toolbar in code, then. E.g. like this: