Macos 使用故事板的Xcode 7中的NSToolbar(NSWindowController->;NSSplitViewController)

Macos 使用故事板的Xcode 7中的NSToolbar(NSWindowController->;NSSplitViewController),macos,swift,xcode7,nstoolbar,nssplitviewcontroller,Macos,Swift,Xcode7,Nstoolbar,Nssplitviewcontroller,您好,我已经看到这个问题被问了好几次,但还没有确定的答案,所以我为xcode 7和swift2创建了它(这可能已经改变了一些事情) 我使用Xcode 7和Cocoa OSX Story boards+swift2创建了一个项目,因此我的项目从一个连接到NSViewController的NSWindowController开始(如预期的那样!)。我在窗口控制器中添加了一个NSToolbar,并在工具栏中添加了一个NSButton。我将我的NSViewController更改为新的NSSplitVi

您好,我已经看到这个问题被问了好几次,但还没有确定的答案,所以我为xcode 7和swift2创建了它(这可能已经改变了一些事情)

我使用Xcode 7和Cocoa OSX Story boards+swift2创建了一个项目,因此我的项目从一个连接到NSViewController的NSWindowController开始(如预期的那样!)。我在窗口控制器中添加了一个NSToolbar,并在工具栏中添加了一个NSButton。我将我的NSViewController更改为新的NSSplitViewController之一,它链接到三个NSViewControllers,并使用垂直分隔符水平显示它们的视图-(类似于您在照片应用程序中看到的布局或Yosemite+中的页面)。我的最终目标是工具栏中的按钮显示和隐藏第一次拆分

我的理解是,我希望为了实现这一点,我应该在NSSplitViewController中创建一个操作,该操作或多或少地改变自动布局约束的计算方式:

然后以某种方式将此操作链接到工具栏中的NSButton。。。它恰好位于NSWindowController中(在层次结构中处于较远和隔离状态)

我已经讨论了有关NSToolbar和故事板的其他问题,但未能实现我的目标:

  • YouTube视频:这是我发现的最接近解决问题的方法,但他的方法不适用于故事板,只创建自己的xib文件
  • 在这个问题上:有人建议使用first reponder创建链接,并希望所有东西都能在运行时连接起来(这看起来有点不可靠,我认为苹果不会采用这种方式来实现…)。另一个人建议在NSWindowController中创建一个视图控制器变量,并从此处操作其属性。。。但还是有点狡猾

  • 我在该问题中看到的一条最新评论似乎是解决该问题的最佳方法(但仍然没有我想的那么好),它是将NSObjectController添加到每个场景的dock中,当场景加载时,将对象的值设置到另一个secene的控制器中。这真的是最好的方法吗?如果是的话,我怎样才能做到这一点

苹果确实在WWDC15中提到(再次)他们为osx和拥有视图控制器的拆分视图控制器创建了故事板,以便您可以将逻辑和工作转移到特定的视图控制器,因此我希望从拆分视图控制器内部做所有事情,因为这是需要更改的目标


有人知道如何从视图控制器本身实现这一点吗?我真的无法找到将我的工具栏项连接到它的方法。

好的,我几天前就提出了这个问题,到目前为止还没有答案,所以我用我最近克服这个问题所做的事情来回答

创建Xcode项目后,我做了以下工作:

  • 为NSSplitViewController创建了子类MySplitViewController
  • 为每个NSSplitViewItem添加了一个IBOutlet。例如:

    @IBOutlet弱var mySplitViewItem:NSSplitViewItem

  • 为NSWindowController创建了一个子类WindowController

  • 在WindowController类中添加了链接到NSToolbarItem(我的按钮)的iAction
  • 添加了一个属性,该属性将窗口控制器的内容作为MySplitViewController获取

    var mySplitViewController:mySplitViewController{ 将self.window?.contentViewController返回为!MySplitViewController }

  • 现在,我可以从我创建的操作中的窗口控制器访问拆分视图控制器的属性:

    mySplitViewController。mySplitViewItem.collapsed=true


我创建了一些这样做的示例代码(但使用视图控制器并更改标签的文本,以防有人希望看到具有这种行为的正在工作的项目。还有一个关于它的示例:)

因此,我正在处理相同的问题,并没有找到与您所经历的相同的解决方案。我读了你的帖子,想知道当我想到使用通知时,我将如何实现你的解决方案。在大约30秒内,我得到了一个完美的工作解决方案:

在windowController中添加一个iAction来发布通知,如下所示

-(IBAction)toggleMasterViewClicked:(id)sender
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"TestNotification" object:nil];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(toggleMasterView:) name:@"TestNotification" object:nil];
将该操作连接到您的
NSToolbarItem
,然后在viewController中添加self作为该通知的观察者,如下所示

-(IBAction)toggleMasterViewClicked:(id)sender
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"TestNotification" object:nil];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(toggleMasterView:) name:@"TestNotification" object:nil];
在您的情况下,选择器应该是
updateMyLabelText

我看不出这有什么坏处。无需参考其他对象,无依赖性。对我来说完美无瑕

一个人提议使用first reponder创建链接,并希望所有东西都能在运行时连接起来(这看起来有点不可靠,我认为苹果不会采用这种方式实现…)

我认为这种急救方法实际上是正确的

例如: 在任何视图控制器中添加类似于以下内容的内容

@IBAction func doSomething(_ sender: AnyObject?) {
    print("Do something.")
}
这将神奇地出现在第一反应器中:

在情节提要中,右键单击窗口控制器上方的橙色“first responder”(第一响应者)图标,您将在很长的列表中看到
doSomething
。您只需将其连接到工具栏按钮

在下面的屏幕截图中,您可以看到我的“切换边栏”按钮连接到我的第一个响应程序中的
toggleSidebar
操作

我甚至不需要编写这个方法-它由
NSSplitViewController
提供:

    @IBAction open func toggleSidebar(_ sender: Any?)

使用此方法时,如果应用程序有多个窗口(例如基于文档),则需要小心。这是因为如果您的代码被用作-